简体   繁体   English

如何编写此查询而不在GROUP BY中包含所有列

[英]How to write this query and not have all columns in GROUP BY

The following query 以下查询

SELECT child.* 
FROM [nested-set] AS parent
JOIN (
  SELECT [lft] AS parentLft, [rgt] AS parentRgt 
  FROM [nested-set] WHERE [id] = 3
) AS parent2 ON 1=1
JOIN [nested-set] AS child ON child.[lft] BETWEEN parent.[lft] AND parent.[rgt] 
WHERE parent.[lft] >= parentLft AND parent.[rgt] < parentRgt AND parent.[id] > 1 
GROUP BY child.[id] 
HAVING COUNT(child.[id]) = 1 
ORDER BY child.[lft] ASC

that gets children of a node in nested set model that runs perfectly fine on MySQL and SQLite (of course with different column quoting) but in order to get it to work on MS SQL Server I have to add all the columns in the GROUP BY clause. 它可以在嵌套集模型中获得节点的子节点,而该节点集可以在MySQL和SQLite上完美运行(当然使用不同的列引用),但是为了使其能够在MS SQL Server上运行,我必须在GROUP BY子句中添加所有列。 Since this query is supposed to run on different tables that only have id, lft and rgt columns in common having to specify all columns each time would be an overkill. 由于该查询应该在仅具有id,lft和rgt列的不同表上运行,因此每次都必须指定所有列将是一个大问题。 Is there a solution for this? 有解决方案吗?

You can just use a subquery that returns the Id's you need, and then link the main table to that. 您可以只使用返回所需ID的子查询,然后将主表链接到该子查询。

That way you don't need to specify the columns in the outer query. 这样,您无需在外部查询中指定列。

SELECT t.* 
FROM(
    SELECT child.id
    FROM [nested-set] headparent
    JOIN [nested-set] parent ON (parent.lft >= headparent.lft AND parent.rgt < headparent.rgt)
    JOIN [nested-set] child ON (child.lft BETWEEN parent.lft AND parent.rgt)
    WHERE headparent.id = 3 
      AND parent.id > 1
    GROUP BY child.id
    HAVING count(*) = 1
) q
JOIN [nested-set] t ON t.id = q.id
ORDER BY t.lft ASC;

And since this is pretty much "Old Standard SQL" (fe doesn't use window functions), this should work also on MySql or SQLite. 并且由于这几乎是“旧标准SQL”(fe不使用窗口函数),因此这在MySql或SQLite上也应适用。

Post scriptum: 投稿时间:

I was wondering if it would be possible to use EXISTS for this. 我想知道是否有可能为此使用EXISTS。
And from the experiment below, it does seem so. 从下面的实验来看,确实如此。 If you don't use a GROUP BY. 如果您不使用GROUP BY。
But imho, the first method is a more straight forward way to pull it off. 但是恕我直言,第一种方法是一种更直接的实现方法。

declare @NestedSet table (id int, lft int, rgt int, colA int);

insert into @NestedSet (id,lft,rgt,colA) values
(1,3,5,100),
(2,4,5,200),
(3,3,6,300),
(4,3,5,400),
(5,4,6,500);

select *
from @NestedSet t
where exists (
    select 1
    from @NestedSet headparent
    join @NestedSet parent on (parent.lft >= headparent.lft and parent.rgt < headparent.rgt and parent.id > 1)
    where headparent.id = 3
    and t.lft between parent.lft and parent.rgt
    having count(*) = 1
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM