1

我有一个数据库,其中有几个表,我试图从中获取一些数据。但由于布局(我对此无能为力),我似乎无法让正常的 JOIN 工作。

我有三张桌子:

  • 约会者
  • 程序
  • 许可人

  • 表中的“datorer”是一些计算机(注册了 AD 名称、房间号和一个用于评论的单元格)。

  • 表中的“程序”是我的组织购买的不同程序。

  • 表中的“volymlicenser”是组织拥有的少数许可证,即批量许可证。

这里的单元格是 ID、RegKey 和 comp_name。

大多数程序是 OEM 许可证,并且只安装在一台计算机上,因此它们不需要像批量许可证一样在另一个表中将程序名称与所属计算机一起注册。

设计数据库时,它只包含最后两个表,不需要连接查询。最近,他们添加了由上述单元格组成的表格“datorer”。

我现在想做的是,最好通过一个查询,查看布尔单元 program.VL 是否设置为 true。

如果是这样,我想在 volymlicenser.RegKey 上加入 progran.RegKey,并从那里获取 volymlicenser.comp_name 的内容。

我尝试使用的查询如下..它不起作用。

SELECT 
    prog.Namn AS Program, prog.comp_name AS Datornamn, 
    pc.room AS Rum, pc.kommentar AS Kommentar
FROM 
    program AS prog
JOIN 
    datorer AS pc ON prog.comp_name = pc.comp_name
JOIN 
    volymlicenser AS vl ON vl.RegKey = prog.RegKey
WHERE 
    prog.Namn = "Adobe Production Premium CS6"

希望可以有人帮帮我。:)

请务必询问是否有不完全清楚的地方!

以下是示例记录和所需结果:

datorer

| id | comp_name | room | kommentar|
|----------------------------------|
| 1  | MB-56C5   | 1.1  | NULL     |
| 2  | MB-569B   | 4.1  | NULL     |

program

| id | Namn | amount | VL | RegKey | comp_name | leveranotor | purchased | note | Suite | SuiteContents |
|-----------------------------------------------------------------------------------------------|
| 1 | Adobe Production Premium CS6 | 2 | 1 | THE-ADOBE-SERIAL | NULL | Atea | 2012-11-01 | Purchased 2012 together with new computers | 1 | The contents of this suite |

| 2 | Windows 7 PRO retail | 1 | 0 | THE-MS-SERIAL | MB-569B | Atea | 2012-11-01 | Purchased 2012 together with new computers | 0 | NULL |

| 3 | Windows 7 PRO retail | 1 | 0 | THE-MS-SERIAL | MB-56C5 | Atea | 2012-11-01 | Purchased 2012 together with new computers | 0 | NULL |

volymlicenser

| id | RegKey           | comp_name |
|-----------------------------------|
|  1 | THE-ADOBE-SERIAL | MB-569B   |

根据 SQL 选择查询的期望结果:

| Program | Computer name | Room | Kommentar|
|-------------------------------------------|
| Adobe Production Premium CS6 | MB-569B | 4.1 | NULL |
|-------------------------------------------|

查询 Windows 7 PRO 零售时所需的结果:

| Program | Computer name | Room | Kommentar|
|-------------------------------------------|
| Windows 7 PRO Retail | MB-569B | 4.1 | NULL |
| Windows 7 PRO Retail | MB-56C5 | 1.1 | NULL |

将“WHERE”更改为“Windows 7 PRO Retail”时的预期结果

简单来说,如果 program.VL 为 1,comp_name 将在 volymlicenser.comp_name 列中找到。

如果 program.VL 为 0,comp_name 将在 program.comp_name 列中找到。

找到 comp_name 后,它需要从 datorer.comp_name 上的任何这些表中加入 comp_name 以获取房间号。

我希望这对你和我一样有意义。

4

3 回答 3

1

看看PROGRAM中的 COMP_NAME ——对于 Adob​​e 产品,它是 NULL。接下来,您编写的第一个常规连接将 Adob​​e 从结果中剔除。所以,在第一次加入之后,你就得到了微软的产品。然后使用 Reg_Key 的第二次连接会得到一个空表,因为剩余的 RegKey 仅引用“THE-MS-SERIAL”。

反而...

SELECT prog.namn, coalesce(vl.comp_name, prog.comp_name), pc.room, pc.kommentar
FROM program as prog LEFT JOIN volymlicenser as vl
ON prog.RegKey = vl.RegKey
LEFT JOIN dataorer as pc
ON coalesce(vl.comp_name, prog.comp_name) = pc.comp_name

使用左连接将保留连接语法左侧的表的内容。这种连接方法是必需的,因为连接键并未通过所有三个表一致地填写。而 coalesce 函数的作用类似于 ifelse 函数。如果第一个变量为空,则将其替换为下一个变量的内容。漂亮。

顺便说一句,我自己没有运行过这个。

于 2013-05-03T04:15:36.703 回答
0

您最好创建 2 个内联表,每个表都有一个 JOIN 配置,然后使用 CASE 来决定从中选择哪个:

SELECT 
    CASE WHEN table1.column1 = "A"
        THEN table2.column2
    ELSE
        table1.column2
    END
FROM
(SELECT t1.id, t1.column1, t2.column2 
FROM t1 INNER JOIN t2 ON t1.x = t2.y) table1 INNER JOIN
(SELECT t1.id, t1.column1, t3.column2 
FROM t1 INNER JOIN t3 ON t1.x = t2.y) table2 ON table1.id = table2.id;
于 2013-05-01T21:32:26.980 回答
0

我正在尝试以下操作:

SELECT 
    CASE WHEN program.VL = "1"
        THEN Volymlicenser.comp_name AS Datornamn
    ELSE
        program.comp_name AS Datornamn
    END
FROM
    (SELECT prog.Namn AS Program, pc.room AS Room, pc.kommentar AS Komentar
    FROM program AS prog INNER JOIN Volymlicenser AS vlic ON vlic.RegKey = prog.RegKey) table1 INNER JOIN
    (SELECT t1.id, t1.column1, t3.column2 
    FROM t1 INNER JOIN t3 ON t1.x = t2.y) table2 ON table1.id = table2.id;

但是在选择的时候停了下来。我真的不明白这里的table1、table2、t1、t2和t3。

loltempast:您(或任何人)能否请您澄清一下,因为我似乎不明白应该如何进行查询。

于 2013-05-02T20:40:29.410 回答