【问题标题】:Using 2 tables to report on a status SQL Query使用 2 个表报告状态 SQL 查询
【发布时间】:2014-07-03 10:56:03
【问题描述】:

我正在写一份报告,为我们的新客户带回 Landstatus's。 我们有 3 个选项(Gold、Silver 和 Bronze,如果用户不在那里添加状态,则为 null)。 数据存储在 2 个不同的表中 dbo.tbl_Profile_ProjectLanddbo.Tasks

有时我发现dbo.tbl_Profile_ProjectLand 的土地状态与dbo.Tasks 不同

对于我的报告,我想使用dbo.tbl_Profile_ProjectLand 作为我的主表,如果这没有土地状态的结果,那么使用dbo.Tasks 中的土地状态

问题是我似乎无法正确查询。 这是我的代码。

SELECT 
Count
            ((CASE WHEN pp.landstatus > 0 THEN pp.landstatus
            ELSE t.landstatus END)) As Taken,
                ls.Description
FROM         dbo.Tasks AS t 
    LEFT JOIN
             tbl_User AS u 
    ON t.TakenBy = u.UserId 
    LEFT JOIN dbo.tbl_Profile_ProjectLand AS pp
ON t.Fk_ProfileID = pp.Fk_ProfileID
    LEFT JOIN
             tbl_DDLandStatus AS ls 
    ON t.LandStatus = ls.Id
    LEFT JOIN 
    dbo.tbl_EnquiryType AS e
    ON t.EnquiryType = e.EnquirytypeId
where
(Month(t.DueDate) = Month(getdate()) 
AND YEAR(t.DueDate) = YEAR(getdate ()))and t.EnquiryType = 1  
GROUP BY 
ls.Description 
ORDER BY ( CASE ls.Description
              WHEN 'Gold - owned' THEN 1
              WHEN 'Silver - identified / offered' THEN 2
              WHEN 'Bronze - no land' THEN 3
              ELSE 0
            END)

这会带来以下结果

Taken   Description
40      NULL
34      Gold - owned
28      Silver - identified / offered
8       Bronze - no land

现在我检查了 40 null 结果,这是不正确的,因为在 dbo.tbl_Profile_ProjectLand 表和 dbo.Tasks 中的 6 表示青铜状态。

我希望我已经解释了这一点,因为我在这里几乎把自己弄糊涂了。 任何帮助将不胜感激。谢谢

我找到了一种方法来做到这一点,但我似乎无法将它们分组。这是我的新代码

SELECT 
COUNT ((CASE WHEN pp.landstatus > 0 THEN pp.landstatus
            ELSE t.landstatus END)) As Taken,
((CASE WHEN ls.Description > '' THEN ls.Description
            ELSE lst.description END)) As 'Description'
FROM dbo.Tasks AS t 
LEFT JOIN tbl_DDLandStatus AS lst
    ON t.landstatus = lst.Id 
LEFT JOIN dbo.tbl_Profile_ProjectLand AS pp
    ON t.Fk_ProfileID = pp.Fk_ProfileID
LEFT JOIN tbl_DDLandStatus AS ls 
    ON pp.LandStatus = ls.Id
WHERE (Month(t.DueDate) = Month(getdate()) 
AND YEAR(t.DueDate) = YEAR(getdate ()))and t.EnquiryType = 1  
GROUP BY 
ls.Description,lst.description
ORDER BY ( CASE ls.Description
              WHEN 'Gold - owned' THEN 1
              WHEN 'Silver - identified / offered' THEN 2
              WHEN 'Bronze - no land' THEN 3
              ELSE 0
            END)

这会带回该结果,该结果是正确的,但没有分组。

Taken   Description
22      NULL
7       Bronze - no land
22      Gold - owned
14      Silver - identified / offered
5       Gold - owned
13      Gold - owned
7       Gold - owned
16      Silver - identified / offered
1       Silver - identified / offered
1       Silver - identified / offered
11      Silver - identified / offered

知道如何按描述对它们进行分组吗?

【问题讨论】:

  • 两个表中实际的 null 计数是多少...
  • landstatus 列有什么值..
  • 嘿,Rusty,你能回应一下吗...
  • 嗨 Azar,null 的计数应该是 28。LandStatus 持有 6 = 青铜 7 = 银和 8 = 金
  • 所以在 tbl_Profile_ProjectLand 表中,土地状态为 NULL,但在任务表中,它设置为 6,应该将其置于青铜状态

标签: sql count left-join case


【解决方案1】:

更改联接的性质以适应状态值的差异是正确的。

我想你也会发现 COUNT() 中不需要 case 表达式

您需要做的就是调整组中的最新查询,以使用与描述列相同的大小写表达式。

SELECT
      COUNT(*) as Taken
    , ((CASE
            WHEN ls.Description > ''
                  THEN ls.Description
            ELSE lst.description
      END)) AS 'Description'
FROM dbo.Tasks AS t
      LEFT JOIN tbl_DDLandStatus AS lst             ON t.landstatus = lst.Id
      LEFT JOIN dbo.tbl_Profile_ProjectLand AS pp   ON t.Fk_ProfileID = pp.Fk_ProfileID
      LEFT JOIN tbl_DDLandStatus AS ls              ON pp.LandStatus = ls.Id
WHERE (MONTH(t.DueDate) = MONTH(GETDATE())
      AND YEAR(t.DueDate) = YEAR(GETDATE()))
      AND t.EnquiryType = 1
GROUP BY
      (CASE
            WHEN ls.Description > ''
                  THEN ls.Description
            ELSE lst.description
      END)
ORDER BY
      (CASE ls.Description
            WHEN 'Gold - owned'
                  THEN 1
            WHEN 'Silver - identified / offered'
                  THEN 2
            WHEN 'Bronze - no land'
                  THEN 3
            ELSE 0
      END)

---


下面:之前的尝试(失败): 不太确定这些:

  • 有 2 个表未引用(计数所需?)
  • case 表达式相当于 count(*),我想你 不需要包含 else,或者做“else NULL”。

试试这个:

SELECT
      COUNT
      (CASE
            WHEN pp.landstatus > 0
                  THEN pp.landstatus
      END)                             AS Taken
    , COALESCE(ls.Description, 'NULL') AS Description
FROM dbo.Tasks AS t
  LEFT JOIN tbl_User AS u                      ON t.TakenBy = u.UserId
  LEFT JOIN dbo.tbl_Profile_ProjectLand AS pp  ON t.Fk_ProfileID = pp.Fk_ProfileID
  LEFT JOIN tbl_DDLandStatus AS ls             ON t.LandStatus = ls.Id
  LEFT JOIN dbo.tbl_EnquiryType AS e           ON t.EnquiryType = e.EnquirytypeId
WHERE (MONTH(t.DueDate) = MONTH(GETDATE())
      AND YEAR(t.DueDate) = YEAR(GETDATE()))
      AND t.EnquiryType = 1
GROUP BY
      COALESCE(ls.Description, 'NULL')
ORDER BY
      (CASE ls.Description
            WHEN 'Gold - owned'
                  THEN 1
            WHEN 'Silver - identified / offered'
                  THEN 2
            WHEN 'Bronze - no land'
                  THEN 3
            ELSE 0
      END)

【讨论】:

  • 嗨,User2067753,这并没有带回我需要的信息,它似乎带回了非常低的定位,我预计会返回几乎 3 倍的数量。
  • 我已经通过将连接的表格返回给您的原件对其进行了修改,大概您需要/想要所有这些表格进行计数。
  • user2067753 它带回了与上次查询伙伴相同的内容。
  • count(whatever) 只要 'whatever' 不为空,就会在计数上加 1
  • 所以,在你的问题中,case 表达式是“whatever”,在我看来,它永远不会得到 NULL,因此 count 与 count(*) 完全相同
【解决方案2】:

你可以这样修改案例并检查

Select count(case when pp.landstatus is not null then pp.landstatus 
              ELSE t.landstatus END) as taken , your query

【讨论】:

  • 这不起作用,它给出的值与 SELECT Count ((CASE WHEN pp.landstatus > 0 THEN pp.landstatus ELSE t.landstatus END)) 一样,
  • 完全相同的结果 Azar
  • 它似乎只带回了“任务”表而不是“tbl_Profile_ProjectLand”的结果
猜你喜欢
  • 1970-01-01
  • 2012-11-17
  • 1970-01-01
  • 2014-03-27
  • 1970-01-01
  • 1970-01-01
  • 2022-12-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多