Access SQL Sub Query or Associative Array Statement - ms-access

Field1 Field2 Field3
A 1 D 'should be dropped
A 1 K 'should be dropped
B 1 K
B 2 K
A 1 P 'should be dropped
A 2 P
A 1 M 'should be dropped
If Field3 = D then ANY ("A" "1") combination should be excluded regardless of Field 3 value. So in this example the first two records should not be returned.

So you have an existing query (we'll call it [TheThirdQuery]) that returns
Field1 Field2 Field3 comment
------ ------ ------ -----------------
A 1 D should be dropped
A 1 K should be dropped
B 1 K
B 2 K
A 1 P should be dropped
A 2 P
A 1 M should be dropped
If you want a query that will omit the rows as indicated in the [comment] column (without using the [comment] column itself), that query would be
SELECT * FROM TheThirdQuery t1
WHERE NOT EXISTS (
SELECT * FROM TheThirdQuery t2
WHERE t2.Field1=t1.Field1
AND t2.Field2=t1.Field2
AND t2.Field3='D'
)

Related

Get count of all types of values in a column obtained in the same SELECT SQL query

MySQL Version: 5.7.36
I'm attempting to minimize the amount of queries I have to execute.
Right now, I'm executing a query similar to this:
SELECT
TABLE 1.column1 as "A",
TABLE 1.column2 as "B"
FROM
TABLE 1
WHERE
CONDITION
I can obtain the results I need from this query, however I would also like to obtain the count of what type of values show up in the same query.
For example, if the following query retrieves this table
A B
- -
1 a
1 b
1 c
2 d
3 e
4 f
4 g
I would also like to, for each row, obtain the count of all rows retrieved with its column "A" that matches its value.
Would it be more efficient to execute another query to get that result or can I modify my obtaining query to get this statistic?
Desired result:
A B C
- - -
1 a 3 # 3 rows with "1" in Column "A"
1 b 3
1 c 3
2 d 1
3 e 1
4 f 2
4 g 2
UPDATE:
The closest query I could find goes like this:
SELECT
TABLE 1.column1 as "A",
COUNT(TABLE 1.column1)
FROM
TABLE 1
WHERE
TABLE 1.column1 = "foo"
GROUP BY
TABLE 1.column1
Results in this:
A B C
- - -
1 a 3
2 d 1
3 e 1
4 f 2
However, it removes any other rows with the same value in column "A". Even if it has different values in column "B". I would like to have all rows present in my SQL query with its corresponding row count.
The next closest query I found goes like this:
SELECT
TABLE 1.column1 as "A",
COUNT(TABLE 1.column1)
FROM
TABLE 1
WHERE
TABLE 1.column1 = "foo"
GROUP BY
TABLE 1.column2
Results in this:
A B C
- - -
1 a 1
1 b 1
1 c 1
2 d 1
3 e 1
4 f 1
4 g 1
Which also isn't achieving the desired result.
You have to join with the subquery that gets the counts.
SELECT t1.column1 AS A, t1.column2 AS B, t2.count
FROM Table1 AS t1
JOIN (
SELECT column1 AS A, COUNT(*) AS count
FROM Table1
GROUP BY column1
) AS t2 ON t1.A = t2.A
SELECT
c,
COUNT(*) OVER (PARTITION BY c)
FROM t
ORDER BY c

How to display row twice with one different specific column, using MySQL?

I have a row that should be duplicated in certain conditions.
Example:
Case 1:
a b c d e
---------------
1 4 25 10 NULL
if e is Null, display a, b and c:
1 4 25
Case 2:
a b c d e
---------------
1 4 25 10 55
if e is not Null, duplicate the row
1 4 25 => column a,b,c
1 4 10 => column a,b,d
Use this query
Using union you can achieve this use case
select a,b,c from table
union all
select a,b,d from table where e is not null
If you don't want to scan the table twice, then you can use cross joinand some logic:
select a, b,
(case when n = 1 then c else d end)
from t cross join
(select 1 as n union all select 2) n
where n = 1 or
(n = 2 and e is not null);

Update rows with where condition returning multiple values

Consider the following two tables
Table A
ID | Name | Price | Size
1 aaa 10 L
2 bbb 12 L
3 ccc 15 L
4 ddd 20 XL
Table B
ID | Type
1 X
2 X
3 Y
4 Z
Now I want to update the price attribute of table A by 1% where the size is L and the Type is X. I wrote this update statement
UPDATE A SET price = price * 1.01
WHERE size = 'L' AND id = (SELECT id FROM B WHERE type = 'X');
But this gives me
ORA-01427: single-row subquery returns more than one row error.
I know that the problem is in "id = (SELECT id FROM B WHERE type = 'X');" because it is giving multiple values.
Give me some idea about how can I resolve this issue.
This select returns 2 rows
SELECT id FROM B WHERE type = 'X'
Result
ID | Type
1 X
2 X
Thus, use IN if you compare value to select that returns multiple rows
UPDATE A
SET price = price * 1.01
WHERE size = 'L'
AND id IN (SELECT id FROM B WHERE type = 'X');
UPDATE a SET a.price = a.price * 1.01 from A a
Inner join B b on a.id = b.id where b.type = 'X' and a. size = 'L' ;

MySQL: Delete records based on maximum value

I have a table containing two foreign keys. I need to delete all rows where key1 & key2 are the same, but val < $x.
key1 & key2 aren't distinct values; there can be multiple records with the same key1 and/or key1/key2 pair.
I've tried several approaches, but can't get anything to work. Every approach thus far results in a MySQL error (such as "can't reopen table") or an incorrect result.
Sample data from the table:
rownum key1 key2 val col col2 col3 col4
1 123 1 2 a b c d
2 123 1 2 e f g h
3 123 2 3 i j k l
4 123 2 3 m n o p
5 456 1 1 q r s t
I need to delete all rows where "val" is < the highest "val" for any given key1/key2 pair.
In other words, for each distinct key1/key2 combo, I need to find the max "val" ($x), and delete any row where val is < $x.
Thus, the desired output after the delete statement is:
rownum key1 key2 val col col2 col3 col4
3 123 2 3 i j k l
4 123 2 3 m n o p
5 456 1 1 q r s t
(col-col4 are irrelevant in determining what records to delete, I included them only to note that the table includes additional columns.)
key1, key2, and "val" are all int type.
How can I delete rows where key1 & key2 are the same, but val < $x?
Use a multi-table delete syntax in which you join the table on itself using the key fields:
DELETE t1 FROM table1 t1, table1 t2
WHERE t1.key1=t2.key1 AND t1.key2=t2.key2 AND t1.val < t2.val
Sqlfiddle - I modified the sample data to have different vals for key pairs.
I'm not sure what your primary key is so I'm just going to call it primary_key
First we need to find the max of key2 for each key1
SELECT key1 as fk1, max(key2) as max_key2 from table group by key1
Then all rows where key2 < max_key2
SELECT t.primary_key as id, s.fk1, s.max_key2, t.key1 from table as t, (SELECT key1 as fk1, max(key2) as max_key2 from table group by key1) as s WHERE t.key2 < s.max_key2 AND s.fk1 = t.key1
Then delete those rows
DELETE from table where primary_key in (SELECT id from (SELECT t.primary_key as id, s.fk1, s.max_key2, t.key1 from table as t, (SELECT key1 as fk1, max(key2) as max_key2 from table group by key1) as s WHERE t.key2 < s.max_key2 AND s.fk1 = t.key1))
I have not tested this but it's roughly how i would go about the problem.
It should go without saying but validate before you delete and have backups

mysql how to select items from Table A where all corresponding items in Table B satisfy condition

I need to obtain all elements m_id of Table A where m_active is = N and that the corresponding elements in Table B have ALL v_active = N.
m_id is foreign key in Table B.
In the example below, what I am looking for is m_id=2 and and m_id=4 as both satisfy the condition of being m_active=N and have ALL v_active = N.
How do I go about that?
Thanks
Table A example:
m_id m_active
1 Y
2 N
3 Y
4 N
Table B example:
v_id m_id v_active
1 1 N
2 1 Y
3 1 N
4 2 N
5 2 N
6 2 N
7 3 N
8 3 Y
9 3 Y
10 4 N
Try this:
SELECT * FROM A
WHERE m_active='N'
AND NOT EXISTS (
SELECT * FROM B
WHERE B.m_id=A.m_id
AND B.v_active<>'N'
);
SELECT *
FROM a
WHERE m_active = 'N'
AND m_id NOT IN
(
SELECT m_id
FROM b
WHERE v_active <> 'N'
)
This will also select all entries from a which have no corresponding entries in b (and hence all 0 of 0 entries are inactive). This may or may not be what you want.