此查询返回多个结果。在底部,您可以看到每个ID号有两个。如何区分我仍然获得25条唯一值记录的记录?
SELECT *
FROM(
SELECT
DISTINCT cards.id, cards.name, cards.created_at, cards.updated_at
FROM cards
INNER JOIN card_process
ON card_process.card_id = cards.id
INNER JOIN processes
ON processes.id = card_process.process_id
INNER JOIN category_process
ON category_process.process_id = processes.id
INNER JOIN categories
ON categories.id = category_process.category_id
INNER JOIN series
ON series.id = categories.serie_id
INNER JOIN serie_user
ON serie_user.serie_id = series.id
AND `cards`.`type` NOT IN ('', 'libraries')
AND NOT `cards`.`deleted`
AND NOT `categories`.`deleted`
AND NOT `series`.`deleted`
AND `cards`.`type` IN ('forms')
AND `series`.`id` IN (124,235,126,126,201,236,207,207,207,207,247,234,131,131,221,225,225,222)
UNION ALL
SELECT
DISTINCT cards.id, cards.name, cards.created_at, cards.updated_at
FROM cards
WHERE `cards`.`account_user_id`='9'
AND NOT `cards`.`deleted`
AND `cards`.`type` IN ('forms')
) AS qry
ORDER BY `updated_at` ASC
LIMIT 0, 25
答案 0 :(得分:3)
不了解您的架构或数据形状,您可以通过简化查询来获得所需内容。假设一个大致符合标准的SQL方言
您不需要附上select
。 完整选择(联合选择表达式)需要order by
,该顺序适用于整个完整选择。
您不需要distinct
中select
个语句的union
关键字:union
本身可以消除重复的行。
并且,当你写一个冗长复杂的查询时,花一些时间格式化它,以便下一个必须理解它的草皮(可能是你几年)可以很容易地做到。
这会让你达到相同的目标:
SELECT cards.id ,
cards.name ,
cards.created_at ,
cards.updated_at
FROM cards
INNER JOIN card_process ON card_process.card_id = cards.id
INNER JOIN processes ON processes.id = card_process.process_id
INNER JOIN category_process ON category_process.process_id = processes.id
INNER JOIN categories ON categories.id = category_process.category_id
INNER JOIN series ON series.id = categories.serie_id
INNER JOIN serie_user ON serie_user.serie_id = series.id
AND `cards`.`type` NOT IN ('', 'libraries')
AND NOT `cards`.`deleted`
AND NOT `categories`.`deleted`
AND NOT `series`.`deleted`
AND `cards`.`type` IN ('forms')
AND `series`.`id` IN (124,235,126,126,201,236,207,207,207,207,247,234,131,131,221,225,225,222)
UNION
SELECT cards.id ,
cards.name ,
cards.created_at ,
cards.updated_at
FROM cards
WHERE `cards`.`account_user_id`='9'
AND NOT `cards`.`deleted`
AND `cards`.`type` IN ('forms')
ORDER BY `updated_at` ASC
LIMIT 0, 25
如果MySql不允许限制完整选择,那么您可能需要附上select
声明。
另外,有人可能会注意到您的加入条件几乎肯定不正确。在第一个选择中,表serie_user
的连接条件有一堆测试:
AND `cards`.`type` NOT IN ('', 'libraries')
AND NOT `cards`.`deleted`
AND NOT `categories`.`deleted`
AND NOT `series`.`deleted`
AND `cards`.`type` IN ('forms')
AND `series`.`id` IN (124,235,126,126,201,236,207,207,207,207,247,234,131,131,221,225,225,222)
他们仅适用于加入serie_user
的候选行。它们不适用于整个结果集。它们应该重构为where
子句和相关表的连接标准,因此:
SELECT cards.id ,
cards.name ,
cards.created_at ,
cards.updated_at
FROM cards
INNER JOIN card_process ON card_process.card_id = cards.id
INNER JOIN processes ON processes.id = card_process.process_id
INNER JOIN category_process ON category_process.process_id = processes.id
INNER JOIN categories ON categories.id = category_process.category_id
AND NOT `categories`.`deleted`
INNER JOIN series ON series.id = categories.serie_id
AND NOT `series`.`deleted`
AND `series`.`id` IN (124,235,126,126,201,236,207,207,207,207,247,234,131,131,221,225,225,222)
INNER JOIN serie_user ON serie_user.serie_id = series.id
WHERE `cards`.`type` NOT IN ('', 'libraries')
AND NOT `cards`.`deleted`
AND `cards`.`type` IN ('forms')
UNION
SELECT cards.id ,
cards.name ,
cards.created_at ,
cards.updated_at
FROM cards
WHERE `cards`.`account_user_id` = '9'
AND NOT `cards`.`deleted`
AND `cards`.`type` IN ('forms')
ORDER BY `updated_at` ASC
LIMIT 0, 25
我要注意的最后一件事是你加入了一大堆未在结果集中使用的表格。您所做的只是从cards
表中获取行的子集。这向我表明,如果你只是摆脱union
和所有无关联,并且只是提出正确的问题,那么你可能会感觉更好。
这完全消除了重复的可能性。
一点点的重构让它归结为此(不能保证我已经100%正确,但你应该能够得到它的要点):
select c.id ,
c.name ,
c.created_at ,
c.updated_at
from cards c
where not c.deleted
and c.type = 'forms'
and ( c.account_user_id = '9'
OR exists ( select *
from card_process cp
join processes p on p.id = cp.process_id
join category_process cpx on cpx.process_id = p.id
join categories c on c.id = cpx.category_id
and not c.deleted
join series s on s.id = categories.serid_id
and not s.deleted
and series.id IN ( 124 , 235 , 126 , ... )
join serie_user su on su.serid_id = s.id
where cp.card_id = c.card_id
)
)
ORDER BY updated_at
LIMIT 0, 25
在复杂的查询中隐藏着一个简单的查询。
答案 1 :(得分:1)
是的,这就是UNION ALL
的工作方式,它只是为您提供了所有查询的所有行。
如果您想删除重复项,请使用UNION
,而不要使用ALL
部分。