4

I need to convert the following two working queries into a single query but everything I try just dies on me for various reasons. My end result is to try to list all software on hand, and show which software is installed and which is not installed for the specific PC being queried. For installed software, list the name, otherwise show NULL for the name. I've tried some sub-select statements in the where clause which gave me a result without an error, but not the right result. Any help is appreciated.

qry1

SELECT device_software.sw_id

FROM Software_device LEFT JOIN Device ON Software_device.d_id = Device.d_id

WHERE Device.d_id = 1;

qry2

SELECT Software.name, Software.sw_id, qry1.sw_id

FROM software LEFT JOIN qry1 ON software.sw_id = qry1.sw_id;

Device Table

------------------
| name  | d_id  |
------------------
| PC1   | 1     |
| PC2   | 2     |
| PC3   | 3     |
------------------

Software Table

------------------
| name  | sw_id |
------------------
| SW_a  | A     |
| SW_b  | B     |
| SW_c  | C     |
| SW_d  | D     |
------------------

Software_Device Table (Many-to-many)

------------------
| d_id  | sw_id |
------------------
| 1     | A     |
| 1     | B     |
| 2     | A     |
| 2     | B     |
| 2     | C     |
------------------

Result Im looking for... (Installed AND uninstalled software on PC1)

---------------------------------
| Sotfware  | pc_id |   name    |
---------------------------------
| SW_a      | 1     |   PC1     |
| SW_b      | 1     |   PC1     |
| SW_c      | NULL  |   NULL    |
| SW_d      | NULL  |   NULL    |
---------------------------------

I listed both mysql and sql tags because I don't think it matters, but just in case it does, i'm using mysql.

4

4 に答える 4

1

要件に基づいて、これにより正しい結果が得られます。

select software.name as Software,
    device.d_id as pc_id,
    device.name as name
from software
    left join device_software
        on device_software.sw_id = software.sw_id
    left join device
        on device_software.d_id = device.d_id
            and device.d_id = 1

注:主キーをテーブルの最初の列として配置することを好みます。また、テーブルに複数形で名前を付けることをお勧めします(デバイス)

于 2012-09-23T05:23:38.500 に答える
1
SELECT 
   s.name AS software, 
   IF((SELECT COUNT(sw.d_id) FROM software_device sw WHERE sw.sw_id = s.sw_id AND d_id = 1) > 0, 1, NULL) AS pc_id, 
    (SELECT d.name FROM device d INNER JOIN software_device sw ON d.d_id = sw.d_id WHERE sw.sw_id = s.sw_id AND d.d_id = 1)  AS name
FROM 
   software s
ORDER BY s.name

EDIT 2:おそらく最も効率的/美しいとは言えませんが、機能します

于 2012-09-23T02:46:37.477 に答える
1

RomanKonz の回答が間違いなく近い場合は、「where」を「on」に移動して、左の結合が適切に機能するようにします。

select software.name as Software,
    device.d_id as pc_id,
    device.name as name
from software
    left join device_software
        on device_software.sw_id = software.sw_id
       and **device_software**.d_id = 1
    left join device
        on device_software.d_id = device.d_id
;
于 2012-09-23T15:58:27.993 に答える
0

以下は、必要なことを行う必要があります。

select s.`name` as `Software`, d.`d_id`, d.`name` as `Device` 
from software s
      left outer join software_device sd 
          on sd.`sw_id` = s.`sw_id` and sd.`d_id` = 1     
      left outer join device d using (`d_id`)  
order by s.`name`
于 2012-09-23T02:46:12.343 に答える