I have a MySQL table with the following schema:
+--------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| country_dest | int(11) | YES | | NULL | |
| type | varchar(56开发者_如何转开发) | YES | | NULL | |
| version | varchar(56) | YES | | NULL | |
+--------------+-------------+------+-----+---------+----------------+
For every country_dest
there will be several type
- business, tourist, etc (but each country_dest may have different or totally unique types).
I want to make sure that for every type, in every country there is a particular value of version
(the same value eg 'complete').
So for instance:
+----+--------------+------------+----------+
| id | country_dest | type | versions |
+----+--------------+------------+----------+
| 1 | 8 | business | single |
| 2 | 8 | business | complete |
| 3 | 8 | tourist | single |
| 4 | 8 | tourist | complete |
| 5 | 8 | diplomatic | single |
| 6 | 14 | business | single |
| 7 | 14 | business | complete |
| 8 | 14 | private | single |
| 9 | 31 | business | double |
| 10 | 31 | business | complete |
+----+--------------+------------+----------+
If that was the table contents, then the query would return that:
country_dest: 8 with type: diplomatic, and country_dest: 14 with type: private
don't have the complete
value.
Output should be:
+---------------+---------------+
| country_dest | type |
+---------------+---------------+
| 8 | diplomatic |
| 14 | private |
+---------------+---------------+
It seems like it would be great to loop through this in a for loop, but that's not how it's done. I've tried lots of solutions but I can't get them to work and I'm sure there must be a tried and tested way of doing this. This is my latest effort:
SELECT form_dest, form_vtype, form_ispack FROM _forms f
WHERE form_dest IN
(SELECT DISTINCT dest.form_dest FROM _forms) dest
AND form_vtype IN
(SELECT DISTINCT form_vtype FROM _forms as type)
AND NOT EXISTS
(SELECT * FROM _forms
WHERE f.form_dest = dest.form_dest
AND f.form_type = type.form_type
AND f.form_ispack = "Yes")
but I get errors.
Grateful for any help on this. Cheers.
Using a NOT EXISTS
should be enough to get the results you require.
To get the entire _forms
record, you can wrap the statement into a subselect and join it again with _forms
.
SQL Statement
SELECT country_dest
, type
FROM _forms invalid
WHERE NOT EXISTS (
SELECT country_dest
, type
FROM _forms valid
WHERE versions = 'complete'
AND valid.country_dest = invalid.country_dest
AND valid.type = invalid.type
)
GROUP BY
country_dest
, type
or equivalent using a DISTINCT
SELECT DISTINCT country_dest
, type
FROM _forms invalid
WHERE NOT EXISTS (
SELECT country_dest
, type
FROM _forms valid
WHERE versions = 'complete'
AND valid.country_dest = invalid.country_dest
AND valid.type = invalid.type
)
Test script (SQL Server)
;WITH _forms (country_dest, type, versions) AS (
SELECT 8, 'business', 'single'
UNION ALL SELECT 8, 'business', 'complete'
UNION ALL SELECT 8, 'tourist', 'single'
UNION ALL SELECT 8, 'tourist', 'complete'
UNION ALL SELECT 8, 'diplomatic', 'single'
UNION ALL SELECT 14, 'business', 'single'
UNION ALL SELECT 14, 'business', 'complete'
UNION ALL SELECT 14, 'private', 'single'
UNION ALL SELECT 31, 'business', 'double'
UNION ALL SELECT 31, 'business', 'complete'
)
SELECT country_dest
, type
FROM _forms f
WHERE NOT EXISTS (
SELECT country_dest
, type
FROM _forms f2
WHERE versions = 'complete'
AND f2.country_dest = f.country_dest
AND f2.type = f.type
)
GROUP BY
country_dest
, type
精彩评论