0
  • TRANS包含事务信息 ( transaction_id, date, foo, bar)
  • ELEM包含事务的元素 ( transaction_id, detail_id)
  • DET包含元素的详细信息 ( detail_id, size, weight, category)

询问:

select * from TRANS t 
join ELEM e on (t.transaction_id = e.transaction_id)
join DET d on (e.detail_id = d.detail_id)

但是,可能具有与其关联TRANS的多个行之一。ELEM/DET因此,如果我有 100 行TRANS并运行查询,我将返回 > 100 行,这是不需要的。

但是,我确实想知道有多少DET行具有d.category=1,但是如果我加入该条件,我会得到 < 100 行(只有具有该条件的行。

我想要蛋糕,也想吃。我想检索TRANS一个日期范围内的所有行,并让我得到结果其中的行数d.category=1。如果d.category != 1那时我不在乎那里有什么,只要该TRANS行仍然返回即可。

4

3 回答 3

2

避免链接 LEFT JOIN。您最终可能会得到意外的数据。

注意:我的意思是,如果您有:

SELECT *
FROM a
LEFT JOIN b 
    ON a = b
LEFT JOIN c
    ON b = c

并且 bc 是严格的 1:1,考虑这样写:

SELECT *
FROM a
LEFT JOIN
(
    SELECT *
    FROM b
    JOIN c
        ON b = c
) d
    ON a = d

所以,你最终会得到类似的东西

SELECT *
FROM TRANS t
LEFT JOIN
(
    SELECT *  -- DON"T USE *, this will fail ^1
    FROM ELEM e
    JOIN DET d
         ON e.detail_id = d.detail_id
) a
    ON t.transaction_id = a.transaction_id

^1 - 您不能在子查询中选择多个具有相同名称的列。明确,永远!!!

于 2012-11-20T17:28:33.263 回答
0

你在寻找这样的东西吗?

SELECT COUNT(1) AS TRANSCOUNT, SUM(CASE WHEN d.category=1 THEN 1 ELSE 0 END) AS CAT1COUNT
FROM TRANS t 
join ELEM e on (t.transaction_id = e.transaction_id)
join DET d on (e.detail_id = d.detail_id)

当 d.category 为 1 时,case 语句将只计算行数(完整连接结果中的每一行为 1)。

好的,我错过了您帖子顶部的表格说明。你可能想要

select count(distinct detail_id)

或者

select count(distinct transaction_id)

也在那里;我不完全确定你要的是哪一个

于 2012-11-20T16:52:35.290 回答
0

这并不完全清楚,但我认为你想先加入ELEMandDET表(有category=1限制),然后LEFT JOINTRANS表加入到前面的构造中(括号根本不需要,它们是为了清楚优先级而添加的):

select t.*, d.* 
from 
        TRANS t 
    left join 
        (     ELEM e 
          join 
              DET d 
            on  d.detail_id = e.detail_id
            and d.category = 1
        ) 
      on  t.transaction_id = e.transaction_id 
where
    ( d.date range_condition ) ;
于 2012-11-20T20:01:32.650 回答