SQL选择基于另一个表中的非空值

时间:2017-05-10 14:28:00

标签: sql sql-server

我正在为工程公司制作一个计划工具。每个工程学科都有一名经理,这些经理需要能够看到他们的学科被分配到的工作。一份工作可能有两个或两个以上的学科。

我有两张桌子。一个是公司正在处理的所有活动工作的列表。它有字段

ID | Job Name | Civil | Mechanical | Electrical |  more disciplines...

具有学科名称的列将保留为该项目的该学科提供的预算的数值。

另一个表适用于系统中的所有用户(经理):

Name   |   Discipline

Users表中的条目包含经理的姓名,然后是他们的纪律,例如“Civil”。此民事经理将能够在民事预算栏中查看所有具有非空值的职位。

我如何选择适用的工作?我想我需要检查登录用户的Users.discipline值,

SELECT discipline FROM Users WHERE name = logged-in-username

但我不知道如何将该值与不同表中具有相同名称的列中是否存在非空值进行比较。

如果您对如何重组这些表格以更好地容纳这样的查询有所了解,我会全力以赴。

使用SQL-Server 2008。

3 个答案:

答案 0 :(得分:3)

如果您真的愿意重组表格,我建议您这样做:

** PROJECTS **
PROJ_ID |Project_Name
1   Project A
2   Project B
3   Project C

** PROJECT_BUDGETS **
PROJ_ID |Discipline |Budget
1        Civil       $4400
1        Mechanical  $2200
1        Electrical  $1200
2        Civil       $7600
2        Electrical  $1600
3        Materials   $3500

** MANAGERS **
MGR_ID|NAME    |DISCIPLINE
1      Bob      Civil
2      Frank    Mechanical
3      Amy      Electrical

要获取项目列表,您可以使用:

SELECT p.PROJECT_ID, b.BUDGET
FROM PROJECTS p LEFT JOIN PROJECT_BUDGETS b ON p.PROJ_ID = b.PROJ_ID
WHERE b.Discipline = (stored value from your logged in user's discipline)

答案 1 :(得分:3)

您将作业数据存储在透视结构中。这确实使某些类型的查询更加棘手。但是,将数据作为子查询忽略并不困难。然后可以更容易地加入所述子查询以解决您的问题。

想象一下,您的架构将预算存储在一个单独的表中,如下所示:

JobId  Discipline Budget
-----  ---------- ------
1      Civil         100
1      Mechanical     50
2      Mechanical     25
2      Electrical     50

然后你的查询将是:

declare @CurrentUser int = ?

select  ...
from    Jobs j
where   j.JobId in (
        select  j.JobId
        from    JobBudgets b
                inner join Users u on
                    u.Discipline = b.Discipline
        where   u.UserId = @CurrentUser
        )

那么,接下来的问题是如何取消现有的Jobs表格。我将演示如何使用CTE,然后可以轻松地使用上述查询。

;with JobBudgets as (
    select  JobId, 'Civil' as Discipline, Civil
    from    Jobs
    where   Civil is not null
    union all
    select  JobId, 'Mechanical', Mechanical
    from    Jobs
    where   Mechanical is not null
    union all
    /* Repeat for each Discipline */
)
select  ... /* This is where you plug in the previous query */

请注意,sql server也支持unpivot语法。随意尝试将其作为练习。

答案 2 :(得分:0)

您可以从table1到table2进行INNER JOIN WHERE table2.value IS NOT NULL 一个例子是:

SELECT *
FROM Users
INNER JOIN Jobs ON Jobs.ID = Users.job_id
WHERE Jobs.<job_name> IS NOT NULL

请注意,您应该根据自己的情况进行调整,这是一个变量,应该是作业名称。

要与空值进行比较,您需要IS NULL或IS NOT NULL,具体取决于您想要的内容。