SQL query Exists AND NOT Exists - mysql

I have a table where I need to insert the data from a view which has 2 conditions :
1) Insert those data in a table where pk is unavailable in a transaction table but is available in the view 2) if pk is there but data is different from the view then insert those data also
Insert into table A
a,
b,
c,
d
SELECT
a,
b,
c,
d
from View sa
WHERE not Exists
(Select * FROM table A q
where SA.a = q.a )
OR
CASE WHEN Exists
(Select * FROM table A q
where SA.a = q.a
AND
SA.b <> q.b
OR SA.c <> q.c
OR SA.d <> q.d
)
Any help appreciated!

I believe this is the proper format for your INSERT with SELECT for Netezza. I removed the invalid CASE expression and there should be no other syntax errors, but not sure about the logic:
Insert into tableA (a,b,c,d) (
SELECT a,b,c,d
from View sa
WHERE not Exists
(Select * FROM tableA q
where SA.a = q.a
)
OR Exists
(Select * FROM tableA q2
where SA.a = q2.a
AND SA.b <> q2.b
OR SA.c <> q2.c
OR SA.d <> q2.d
)
)
Edit: I think it may have been complaining about the re-use of the q table alias.

As a general rule, correlated subqueries are not for Netezza. Obviously you can use them in many cases, but often at the cost of turning an MPP platform into a serial processor. Bad.
You can rewrite your insert a number of ways, but this seems the clearest to me. I have no idea what this logic is trying to do, but I replicated it nonetheless. You may have an issue if view contains duplicates; this can be addressed with a little more knowledge of your data.
insert into tableA (
a
,b
,c
,d
)
select
viw.a
,viw.b
,viw.c
,viw.d
from
view viw
join tableA tba on
(viw.a = tba.a)
or (
viw.a = tba.a
and viw.b <> tba.b
or viw.c <> tba.c
or viw.d <> tba.d
)
You could remove the possibility of view duplicates by inserting into tableA from an actual table and use the rowids found there. Perhaps something like this:
create temporary table temp_view as
select * from view
distribute on (some_key);
Then collect rowids to insert like so:
insert into tableA (
a
,b
,c
,d
)
with mar as ( --Match 'a' records.
select
viw.rowid insert_rowid
from
temp_view viw
join tableA tba using (a)
), mnb as ( --Match against 'b'
select
viw.rowid
from
temp_view viw
join tableA tba on
viw.a = tba.a
and viw.b <> tba.b
or viw.c <> tba.c
or viw.d <> tba.d
), rws as ( --All rowids.
select * from mar
union select * from mnb
)
select
a
,b
,c
,d
from
temp_view viw
join rws on rws.insert_rowid = viw.rowid;

Related

1093 You can't specify target table 'ProgressStepsAcademicPeriod' for update in FROM clause when updating same table used with multiple subqueries [duplicate]

I have a simple mysql table:
CREATE TABLE IF NOT EXISTS `pers` (
`persID` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(35) NOT NULL,
`gehalt` int(11) NOT NULL,
`chefID` int(11) DEFAULT NULL,
PRIMARY KEY (`persID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
INSERT INTO `pers` (`persID`, `name`, `gehalt`, `chefID`) VALUES
(1, 'blb', 1000, 3),
(2, 'as', 1000, 3),
(3, 'chef', 1040, NULL);
I tried to run following update, but I get only the error 1093:
UPDATE pers P
SET P.gehalt = P.gehalt * 1.05
WHERE (P.chefID IS NOT NULL
OR gehalt <
(SELECT (
SELECT MAX(gehalt * 1.05)
FROM pers MA
WHERE MA.chefID = MA.chefID)
AS _pers
))
I searched for the error and found from mysql following page http://dev.mysql.com/doc/refman/5.1/en/subquery-restrictions.html, but it doesn't help me.
What shall I do to correct the sql query?
The problem is that MySQL, for whatever inane reason, doesn't allow you to write queries like this:
UPDATE myTable
SET myTable.A =
(
SELECT B
FROM myTable
INNER JOIN ...
)
That is, if you're doing an UPDATE/INSERT/DELETE on a table, you can't reference that table in an inner query (you can however reference a field from that outer table...)
The solution is to replace the instance of myTable in the sub-query with (SELECT * FROM myTable), like this
UPDATE myTable
SET myTable.A =
(
SELECT B
FROM (SELECT * FROM myTable) AS something
INNER JOIN ...
)
This apparently causes the necessary fields to be implicitly copied into a temporary table, so it's allowed.
I found this solution here. A note from that article:
You don’t want to just SELECT * FROM table in the subquery in real life; I just wanted to keep the examples simple. In reality, you should only be selecting the columns you need in that innermost query, and adding a good WHERE clause to limit the results, too.
You can make this in three steps:
CREATE TABLE test2 AS
SELECT PersId
FROM pers p
WHERE (
chefID IS NOT NULL
OR gehalt < (
SELECT MAX (
gehalt * 1.05
)
FROM pers MA
WHERE MA.chefID = p.chefID
)
)
...
UPDATE pers P
SET P.gehalt = P.gehalt * 1.05
WHERE PersId
IN (
SELECT PersId
FROM test2
)
DROP TABLE test2;
or
UPDATE Pers P, (
SELECT PersId
FROM pers p
WHERE (
chefID IS NOT NULL
OR gehalt < (
SELECT MAX (
gehalt * 1.05
)
FROM pers MA
WHERE MA.chefID = p.chefID
)
)
) t
SET P.gehalt = P.gehalt * 1.05
WHERE p.PersId = t.PersId
In Mysql, you can not update one table by subquery the same table.
You can separate the query in two parts, or do
UPDATE TABLE_A AS A
INNER JOIN TABLE_A AS B ON A.field1 = B.field1
SET field2 = ?
Make a temporary table (tempP) from a subquery
UPDATE pers P
SET P.gehalt = P.gehalt * 1.05
WHERE P.persID IN (
SELECT tempP.tempId
FROM (
SELECT persID as tempId
FROM pers P
WHERE
P.chefID IS NOT NULL OR gehalt <
(SELECT (
SELECT MAX(gehalt * 1.05)
FROM pers MA
WHERE MA.chefID = MA.chefID)
AS _pers
)
) AS tempP
)
I've introduced a separate name (alias) and give a new name to 'persID' column for temporary table
It's quite simple. For example, instead of writing:
INSERT INTO x (id, parent_id, code) VALUES (
NULL,
(SELECT id FROM x WHERE code='AAA'),
'BBB'
);
you should write
INSERT INTO x (id, parent_id, code)
VALUES (
NULL,
(SELECT t.id FROM (SELECT id, code FROM x) t WHERE t.code='AAA'),
'BBB'
);
or similar.
The Approach posted by BlueRaja is slow I modified it as
I was using to delete duplicates from the table. In case it helps anyone with large tables
Original Query
DELETE FROM table WHERE id NOT IN (SELECT MIN(id) FROM table GROUP BY field 2)
This is taking more time:
DELETE FROM table WHERE ID NOT IN(
SELECT MIN(t.Id) FROM (SELECT Id, field2 FROM table) AS t GROUP BY field2)
Faster Solution
DELETE FROM table WHERE ID NOT IN(
SELECT t.Id FROM (SELECT MIN(Id) AS Id FROM table GROUP BY field2) AS t)
MySQL doesn't allow selecting from a table and update in the same table at the same time. But there is always a workaround :)
This doesn't work >>>>
UPDATE table1 SET col1 = (SELECT MAX(col1) from table1) WHERE col1 IS NULL;
But this works >>>>
UPDATE table1 SET col1 = (SELECT MAX(col1) FROM (SELECT * FROM table1) AS table1_new) WHERE col1 IS NULL;
MariaDB has lifted this starting from 10.3.x (both for DELETE and UPDATE):
UPDATE - Statements With the Same Source and Target
From MariaDB 10.3.2, UPDATE statements may have the same source and target.
Until MariaDB 10.3.1, the following UPDATE statement would not work:
UPDATE t1 SET c1=c1+1 WHERE c2=(SELECT MAX(c2) FROM t1);
ERROR 1093 (HY000): Table 't1' is specified twice,
both as a target for 'UPDATE' and as a separate source for data
From MariaDB 10.3.2, the statement executes successfully:
UPDATE t1 SET c1=c1+1 WHERE c2=(SELECT MAX(c2) FROM t1);
DELETE - Same Source and Target Table
Until MariaDB 10.3.1, deleting from a table with the same source and target was not possible. From MariaDB 10.3.1, this is now possible. For example:
DELETE FROM t1 WHERE c1 IN (SELECT b.c1 FROM t1 b WHERE b.c2=0);
DBFiddle MariaDB 10.2 - Error
DBFiddle MariaDB 10.3 - Success
Just as reference, you can also use Mysql Variables to save temporary results, e.g.:
SET #v1 := (SELECT ... );
UPDATE ... SET ... WHERE x=#v1;
https://dev.mysql.com/doc/refman/5.7/en/user-variables.html
If you are trying to read fieldA from tableA and save it on fieldB on the same table, when fieldc = fieldd you might want consider this.
UPDATE tableA,
tableA AS tableA_1
SET
tableA.fieldB= tableA_1.filedA
WHERE
(((tableA.conditionFild) = 'condition')
AND ((tableA.fieldc) = tableA_1.fieldd));
Above code copies the value from fieldA to fieldB when condition-field met your condition. this also works in ADO (e.g access )
source: tried myself
Other workarounds include using SELECT DISTINCT or LIMIT in the subquery, although these are not as explicit in their effect on materialization. this worked for me
as mentioned in MySql Doc

Update empty values in column from the same column [duplicate]

I have a simple mysql table:
CREATE TABLE IF NOT EXISTS `pers` (
`persID` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(35) NOT NULL,
`gehalt` int(11) NOT NULL,
`chefID` int(11) DEFAULT NULL,
PRIMARY KEY (`persID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
INSERT INTO `pers` (`persID`, `name`, `gehalt`, `chefID`) VALUES
(1, 'blb', 1000, 3),
(2, 'as', 1000, 3),
(3, 'chef', 1040, NULL);
I tried to run following update, but I get only the error 1093:
UPDATE pers P
SET P.gehalt = P.gehalt * 1.05
WHERE (P.chefID IS NOT NULL
OR gehalt <
(SELECT (
SELECT MAX(gehalt * 1.05)
FROM pers MA
WHERE MA.chefID = MA.chefID)
AS _pers
))
I searched for the error and found from mysql following page http://dev.mysql.com/doc/refman/5.1/en/subquery-restrictions.html, but it doesn't help me.
What shall I do to correct the sql query?
The problem is that MySQL, for whatever inane reason, doesn't allow you to write queries like this:
UPDATE myTable
SET myTable.A =
(
SELECT B
FROM myTable
INNER JOIN ...
)
That is, if you're doing an UPDATE/INSERT/DELETE on a table, you can't reference that table in an inner query (you can however reference a field from that outer table...)
The solution is to replace the instance of myTable in the sub-query with (SELECT * FROM myTable), like this
UPDATE myTable
SET myTable.A =
(
SELECT B
FROM (SELECT * FROM myTable) AS something
INNER JOIN ...
)
This apparently causes the necessary fields to be implicitly copied into a temporary table, so it's allowed.
I found this solution here. A note from that article:
You don’t want to just SELECT * FROM table in the subquery in real life; I just wanted to keep the examples simple. In reality, you should only be selecting the columns you need in that innermost query, and adding a good WHERE clause to limit the results, too.
You can make this in three steps:
CREATE TABLE test2 AS
SELECT PersId
FROM pers p
WHERE (
chefID IS NOT NULL
OR gehalt < (
SELECT MAX (
gehalt * 1.05
)
FROM pers MA
WHERE MA.chefID = p.chefID
)
)
...
UPDATE pers P
SET P.gehalt = P.gehalt * 1.05
WHERE PersId
IN (
SELECT PersId
FROM test2
)
DROP TABLE test2;
or
UPDATE Pers P, (
SELECT PersId
FROM pers p
WHERE (
chefID IS NOT NULL
OR gehalt < (
SELECT MAX (
gehalt * 1.05
)
FROM pers MA
WHERE MA.chefID = p.chefID
)
)
) t
SET P.gehalt = P.gehalt * 1.05
WHERE p.PersId = t.PersId
In Mysql, you can not update one table by subquery the same table.
You can separate the query in two parts, or do
UPDATE TABLE_A AS A
INNER JOIN TABLE_A AS B ON A.field1 = B.field1
SET field2 = ?
Make a temporary table (tempP) from a subquery
UPDATE pers P
SET P.gehalt = P.gehalt * 1.05
WHERE P.persID IN (
SELECT tempP.tempId
FROM (
SELECT persID as tempId
FROM pers P
WHERE
P.chefID IS NOT NULL OR gehalt <
(SELECT (
SELECT MAX(gehalt * 1.05)
FROM pers MA
WHERE MA.chefID = MA.chefID)
AS _pers
)
) AS tempP
)
I've introduced a separate name (alias) and give a new name to 'persID' column for temporary table
It's quite simple. For example, instead of writing:
INSERT INTO x (id, parent_id, code) VALUES (
NULL,
(SELECT id FROM x WHERE code='AAA'),
'BBB'
);
you should write
INSERT INTO x (id, parent_id, code)
VALUES (
NULL,
(SELECT t.id FROM (SELECT id, code FROM x) t WHERE t.code='AAA'),
'BBB'
);
or similar.
The Approach posted by BlueRaja is slow I modified it as
I was using to delete duplicates from the table. In case it helps anyone with large tables
Original Query
DELETE FROM table WHERE id NOT IN (SELECT MIN(id) FROM table GROUP BY field 2)
This is taking more time:
DELETE FROM table WHERE ID NOT IN(
SELECT MIN(t.Id) FROM (SELECT Id, field2 FROM table) AS t GROUP BY field2)
Faster Solution
DELETE FROM table WHERE ID NOT IN(
SELECT t.Id FROM (SELECT MIN(Id) AS Id FROM table GROUP BY field2) AS t)
MySQL doesn't allow selecting from a table and update in the same table at the same time. But there is always a workaround :)
This doesn't work >>>>
UPDATE table1 SET col1 = (SELECT MAX(col1) from table1) WHERE col1 IS NULL;
But this works >>>>
UPDATE table1 SET col1 = (SELECT MAX(col1) FROM (SELECT * FROM table1) AS table1_new) WHERE col1 IS NULL;
MariaDB has lifted this starting from 10.3.x (both for DELETE and UPDATE):
UPDATE - Statements With the Same Source and Target
From MariaDB 10.3.2, UPDATE statements may have the same source and target.
Until MariaDB 10.3.1, the following UPDATE statement would not work:
UPDATE t1 SET c1=c1+1 WHERE c2=(SELECT MAX(c2) FROM t1);
ERROR 1093 (HY000): Table 't1' is specified twice,
both as a target for 'UPDATE' and as a separate source for data
From MariaDB 10.3.2, the statement executes successfully:
UPDATE t1 SET c1=c1+1 WHERE c2=(SELECT MAX(c2) FROM t1);
DELETE - Same Source and Target Table
Until MariaDB 10.3.1, deleting from a table with the same source and target was not possible. From MariaDB 10.3.1, this is now possible. For example:
DELETE FROM t1 WHERE c1 IN (SELECT b.c1 FROM t1 b WHERE b.c2=0);
DBFiddle MariaDB 10.2 - Error
DBFiddle MariaDB 10.3 - Success
Just as reference, you can also use Mysql Variables to save temporary results, e.g.:
SET #v1 := (SELECT ... );
UPDATE ... SET ... WHERE x=#v1;
https://dev.mysql.com/doc/refman/5.7/en/user-variables.html
If you are trying to read fieldA from tableA and save it on fieldB on the same table, when fieldc = fieldd you might want consider this.
UPDATE tableA,
tableA AS tableA_1
SET
tableA.fieldB= tableA_1.filedA
WHERE
(((tableA.conditionFild) = 'condition')
AND ((tableA.fieldc) = tableA_1.fieldd));
Above code copies the value from fieldA to fieldB when condition-field met your condition. this also works in ADO (e.g access )
source: tried myself
Other workarounds include using SELECT DISTINCT or LIMIT in the subquery, although these are not as explicit in their effect on materialization. this worked for me
as mentioned in MySql Doc

Update table not working with sub-selects [duplicate]

I have a simple mysql table:
CREATE TABLE IF NOT EXISTS `pers` (
`persID` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(35) NOT NULL,
`gehalt` int(11) NOT NULL,
`chefID` int(11) DEFAULT NULL,
PRIMARY KEY (`persID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
INSERT INTO `pers` (`persID`, `name`, `gehalt`, `chefID`) VALUES
(1, 'blb', 1000, 3),
(2, 'as', 1000, 3),
(3, 'chef', 1040, NULL);
I tried to run following update, but I get only the error 1093:
UPDATE pers P
SET P.gehalt = P.gehalt * 1.05
WHERE (P.chefID IS NOT NULL
OR gehalt <
(SELECT (
SELECT MAX(gehalt * 1.05)
FROM pers MA
WHERE MA.chefID = MA.chefID)
AS _pers
))
I searched for the error and found from mysql following page http://dev.mysql.com/doc/refman/5.1/en/subquery-restrictions.html, but it doesn't help me.
What shall I do to correct the sql query?
The problem is that MySQL, for whatever inane reason, doesn't allow you to write queries like this:
UPDATE myTable
SET myTable.A =
(
SELECT B
FROM myTable
INNER JOIN ...
)
That is, if you're doing an UPDATE/INSERT/DELETE on a table, you can't reference that table in an inner query (you can however reference a field from that outer table...)
The solution is to replace the instance of myTable in the sub-query with (SELECT * FROM myTable), like this
UPDATE myTable
SET myTable.A =
(
SELECT B
FROM (SELECT * FROM myTable) AS something
INNER JOIN ...
)
This apparently causes the necessary fields to be implicitly copied into a temporary table, so it's allowed.
I found this solution here. A note from that article:
You don’t want to just SELECT * FROM table in the subquery in real life; I just wanted to keep the examples simple. In reality, you should only be selecting the columns you need in that innermost query, and adding a good WHERE clause to limit the results, too.
You can make this in three steps:
CREATE TABLE test2 AS
SELECT PersId
FROM pers p
WHERE (
chefID IS NOT NULL
OR gehalt < (
SELECT MAX (
gehalt * 1.05
)
FROM pers MA
WHERE MA.chefID = p.chefID
)
)
...
UPDATE pers P
SET P.gehalt = P.gehalt * 1.05
WHERE PersId
IN (
SELECT PersId
FROM test2
)
DROP TABLE test2;
or
UPDATE Pers P, (
SELECT PersId
FROM pers p
WHERE (
chefID IS NOT NULL
OR gehalt < (
SELECT MAX (
gehalt * 1.05
)
FROM pers MA
WHERE MA.chefID = p.chefID
)
)
) t
SET P.gehalt = P.gehalt * 1.05
WHERE p.PersId = t.PersId
In Mysql, you can not update one table by subquery the same table.
You can separate the query in two parts, or do
UPDATE TABLE_A AS A
INNER JOIN TABLE_A AS B ON A.field1 = B.field1
SET field2 = ?
Make a temporary table (tempP) from a subquery
UPDATE pers P
SET P.gehalt = P.gehalt * 1.05
WHERE P.persID IN (
SELECT tempP.tempId
FROM (
SELECT persID as tempId
FROM pers P
WHERE
P.chefID IS NOT NULL OR gehalt <
(SELECT (
SELECT MAX(gehalt * 1.05)
FROM pers MA
WHERE MA.chefID = MA.chefID)
AS _pers
)
) AS tempP
)
I've introduced a separate name (alias) and give a new name to 'persID' column for temporary table
It's quite simple. For example, instead of writing:
INSERT INTO x (id, parent_id, code) VALUES (
NULL,
(SELECT id FROM x WHERE code='AAA'),
'BBB'
);
you should write
INSERT INTO x (id, parent_id, code)
VALUES (
NULL,
(SELECT t.id FROM (SELECT id, code FROM x) t WHERE t.code='AAA'),
'BBB'
);
or similar.
The Approach posted by BlueRaja is slow I modified it as
I was using to delete duplicates from the table. In case it helps anyone with large tables
Original Query
DELETE FROM table WHERE id NOT IN (SELECT MIN(id) FROM table GROUP BY field 2)
This is taking more time:
DELETE FROM table WHERE ID NOT IN(
SELECT MIN(t.Id) FROM (SELECT Id, field2 FROM table) AS t GROUP BY field2)
Faster Solution
DELETE FROM table WHERE ID NOT IN(
SELECT t.Id FROM (SELECT MIN(Id) AS Id FROM table GROUP BY field2) AS t)
MySQL doesn't allow selecting from a table and update in the same table at the same time. But there is always a workaround :)
This doesn't work >>>>
UPDATE table1 SET col1 = (SELECT MAX(col1) from table1) WHERE col1 IS NULL;
But this works >>>>
UPDATE table1 SET col1 = (SELECT MAX(col1) FROM (SELECT * FROM table1) AS table1_new) WHERE col1 IS NULL;
MariaDB has lifted this starting from 10.3.x (both for DELETE and UPDATE):
UPDATE - Statements With the Same Source and Target
From MariaDB 10.3.2, UPDATE statements may have the same source and target.
Until MariaDB 10.3.1, the following UPDATE statement would not work:
UPDATE t1 SET c1=c1+1 WHERE c2=(SELECT MAX(c2) FROM t1);
ERROR 1093 (HY000): Table 't1' is specified twice,
both as a target for 'UPDATE' and as a separate source for data
From MariaDB 10.3.2, the statement executes successfully:
UPDATE t1 SET c1=c1+1 WHERE c2=(SELECT MAX(c2) FROM t1);
DELETE - Same Source and Target Table
Until MariaDB 10.3.1, deleting from a table with the same source and target was not possible. From MariaDB 10.3.1, this is now possible. For example:
DELETE FROM t1 WHERE c1 IN (SELECT b.c1 FROM t1 b WHERE b.c2=0);
DBFiddle MariaDB 10.2 - Error
DBFiddle MariaDB 10.3 - Success
Just as reference, you can also use Mysql Variables to save temporary results, e.g.:
SET #v1 := (SELECT ... );
UPDATE ... SET ... WHERE x=#v1;
https://dev.mysql.com/doc/refman/5.7/en/user-variables.html
If you are trying to read fieldA from tableA and save it on fieldB on the same table, when fieldc = fieldd you might want consider this.
UPDATE tableA,
tableA AS tableA_1
SET
tableA.fieldB= tableA_1.filedA
WHERE
(((tableA.conditionFild) = 'condition')
AND ((tableA.fieldc) = tableA_1.fieldd));
Above code copies the value from fieldA to fieldB when condition-field met your condition. this also works in ADO (e.g access )
source: tried myself
Other workarounds include using SELECT DISTINCT or LIMIT in the subquery, although these are not as explicit in their effect on materialization. this worked for me
as mentioned in MySql Doc

How can I optimize this MySQL query in a stored procedure?

SET #count := (SELECT count(*)
FROM dbo.ManyToManyTable SRSG
JOIN tableA SG on SRSG.a = SG.a
JOIN tableB SR on SRSG.b = SR.a
WHERE SR.c = INPUT_VALUE);
IF (#count > 0)
THEN
SELECT SG.fieldA, SG.fieldB
FROM dbo.ManyToManyTable SRSG
JOIN tableA SG on SRSG.a = SG.a
JOIN tableB SR on SRSG.b = SR.a
WHERE SR.c = INPUT_VALUE;
ELSE
SELECT SG.a, SG.b FROM dbo.tableA SG WHERE SG.b = "default value";
END IF;
It's for a MySQL database. This works for me, but I don't like the duplicate select query. However, I have no idea how to fix it under the constraint which is the logic has be within one stored procedure.
You could write this as a single query:
with cte as (
SELECT SG.fieldA, SG.fieldB
FROM dbo.ManyToManyTable SRSG JOIN
tableA SG
on SRSG.salesGroupId = SG.salesGroupId JOIN
tableB SR
on SRSG.salesRegionId = SR.salesRegionId
WHERE SR.AField = INPUT_VALUE
)
select *
from cte
union all
select SG.a, SG.b
from dbo.tableA SG
where SG.b = 'default value' and
not exists (select 1 from cte);
MySQL tends to materialize CTEs (always?), so this should run the query once rather than twice.
A quick, but partial speedup is to replace
SET #count = ( SELECT COUNT(*) ... );
IF (#count > 0)
with this (using the rest of that initial SELECT):
IF ( EXISTS ( SELECT 1 FROM ... ) )
Also for performance, be sure to have in SRSG:
PRIMARY KEY(a,b)
INDEX(b,a)
and don't bother with an AUTO_INCREMENT.

WITH clause in MySQL?

Does MySQL support common table expressions? For example in Oracle there's the WITH clause? :
WITH aliasname
AS
( SELECT COUNT(*) FROM table_name )
SELECT COUNT(*) FROM dept,aliasname
SELECT t.name,
t.num
FROM TABLE t
JOIN (SELECT c.id,COUNT(*) 'num1'
FROM TABLE1 c
WHERE c.column = 'a'
GROUP BY c.id) ta1 ON ta1.id = t.id
JOIN (SELECT d.id,COUNT(*) 'num2'
FROM TABLE2 d
WHERE d.column = 'a'
GROUP BY d.id) ta2 ON ta2.id = t.id
One way is to use a subquery:
SELECT COUNT(*)
FROM dept,
(
SELECT COUNT(*)
FROM table_name
) AS aliasname
Note that the , between the two tables will cross join the two tables the same as in your query you posted. IF there is any relation between them you can JOIN them instead.
No, MySQL does not support Common Table Expressions (CTE). So instead of using WITH tablealias as (....), you will have to do a subquery.
For example,
WITH totalcount AS
(select userid, count(*) as tot from logins group by userid)
SELECT a.firstname, a.lastname, b.tot
FROM users a
INNER JOIN
totalcount b
on a.userid = b.userid
can be re-written in MySQL as
SELECT a.firstname, a.lastname, b.totalcount
FROM users a
INNER JOIN
(select userid, count(*) as tot from logins group by userid) b
on a.userid = b.userid
So let's talk about WITH clause .
WITH clause and INNER JOIN otherwise JOIN are a kind of same , but WITH clause gives you much more latitude especially in WHERE clause ;
I am going to make a view that'll get values like count of users , user name and etc.
First (Creating our tables users and inserted_users) :
inserted_users table :
CREATE TABLE users (id BIGINT(10) AUTO INCEREMENT PRIMARY KEY , name VARCHAR(50))
users table :
CREATE TABLE users (id BIGINT(10) AUTO INCEREMENT PRIMARY KEY , name VARCHAR(50) , gender TINYINT(1))
Second (Inserting some values to work with) :
users table :
INSERT INTO users (name,gender) VALUES ('Abolfazl M' , 1)
I don't want to insert into inserted_users by query , but I want to add a TRUGGER which will insert data automatically to users_inserted table before data be inserted into users table.
Third (Creating trigger add_uinserted) :
DELIMITER $$
CREATE TRIGGER IF NOT EXISTS add_uinserted BEFORE INSERT ON users FOR EACH ROW
BEGIN
IF NEW.name <> '' THEN
INSERT INTO users_inserted (name) VALUES (NEW.name);
ELSE
INSERT INTO users (name,gender) VALUES ('Unknown',NEW.gender);
INSERT INTO users_inserted (name) VALUES ('Unknown');
END IF;
END$$
DELIMITER ;
Run the query and the trigger will be created and at last let's create a view to give us result from a query having WITH clause .
CREATE VIEW select_users AS
WITH GetCAll AS (
SELECT u1.id As Uid ,COUNT(u1.name) AS CnAll FROM users u1
)
SELECT u1.name AS NAME,CASE
WHEN s1.gender = 1 THEN "MALE"
WHEN s1.gender = 0 THEN "FEMALE"
ELSE "UNKNOWN"
END AS GENDER,CASE
WHEN u1.id = gca.Uid THEN "INSERTED TO users_inserted"
ELSE "NOT INSERTED TO users_inserted"
END AS INSERTED,gca.CnAll FROM GetCAll AS gca INNER JOIN users u1;
After you query got ran the view will be created and by calling the view select_users the data will be shown
Last step (calling the select_users view) :
SELECT * FROM select_users
Thanks for taking a look at my answer , and that's it !!