Different actions based on SELECT result - mysql

There are 3 tables (First, Second and Third). I need to check condition in table First and then make an action in Second or Third depend on the result. As it is a huge dataset I prefer to have it in one query instead scripting with PHP or so row by row.
The pseudocode could look like follows:
SELECT status FROM First WHERE userid=.... ;
IF 'status' = 2 THEN INSERT INTO Second (...)
ELSE INSERT INTO Third (...);
It can be converted to the form:
SELECT Count(*) AS cnt FROM First WHERE status=2 AND userid=.... ;
IF #cnt>0 INSERT INTO Second (...)
ELSE INSERT INTO Third (...);
The problem is that MySQL seems to not see the value of #cnt nor there is IF...ELSE... statement in MySQL for queries as far as I know (I may be wrong).

You may use 2 queries:
INSERT INTO Second ( {columns to be inserted into} )
SELECT {values to be inserted}
WHERE EXISTS (
SELECT status
FROM First
WHERE userid=....
AND status = 2
);
INSERT INTO Third ( {columns to be inserted into} )
SELECT {values to be inserted}
WHERE NOT EXISTS (
SELECT status
FROM First
WHERE userid=....
AND status = 2
);
Or use stored procedure.

Related

Merge stored procedure with datatype conversions

I am able to execute my stored procedure. When I execute it a second time instead of updating the existing values same values from source are inserted as new values.
i.e my target has
1
2
3
When I run the stored procedure a second time, instead of updating 1,2,3, it is inserting the same
1
2
3
1
2
3
My condition for when matched then select S.REPORT_TEST1 except T.REPORT_TEST1 is not working.
When I use the same code on a different table which doesn't have data conversions I am able to update.
Can anyone tell where am I going wrong?
CREATE PROCEDURE [dbo].[Merge]
INSERT INTO .[dbo].[TARGET](REPORT_TEST1, REPORT_TEST2, REPOST_TEST3)
FROM (MERGE [dbo].[TARGET] T
USING (SELECT
Cast([REPORT TEST1] as int) [REPORT_TEST1],
Cast([REPORT TEST2] as int) [REPORT_TEST2],
Cast([REPORT TEST3] as int) [REPORT_TEST3]
FROM
[dbo].[SOURCE]) S ON (T.[REPORT_TEST1] = S.[REPORT_TEST1])
WHEN NOT MATCHED BY TARGET
THEN INSERT
VALUES (S.REPORT_TEST1, S.REPORT_TEST2, S.REPOST_TEST3)
WHEN MATCHED
AND EXISTS (SELECT S.REPORT_TEST1, S.REPORT_TEST2, S.REPOST_TEST3
EXCEPT
SELECT T.REPORT_TEST1, T.REPORT_TEST2, T.REPOST_TEST3)
OUTPUT $ACTION ACTION_OUT,
S.REPORT_TEST1, S.REPORT_TEST2, S.REPOST_TEST3) ;
Thanks
would it not suffice to rewrite your WHEN MATCHED statement thusly:
WHEN MATCHED
AND S.REPORT_TEST2 <> T.REPORT_TEST2
AND S.REPORT_TEST3 <> T.REPORT_TEST3
(
SELECT
S.REPORT_TEST1
,S.REPORT_TEST2
,S.REPOST_TEST3
)
I think I understand what you're trying to do, but inside the MERGE context, you're only comparing this row with that row, not the source row against the whole target table. you could modify the subselect thusly if you're trying to query "this source is not at all in the target"
WHEN MATCHED AND EXISTS
(
SELECT
S.REPORT_TEST1
,S.REPORT_TEST2
,S.REPOST_TEST3
EXCEPT SELECT
T2.REPORT_TEST1
,T2.REPORT_TEST2
,T2.REPOST_TEST3
FROM
[dbo].[TARGET] T2
)

SQL Compare rows

Okay here is the situation:
I the following data in a table.
PAIR_NO NO NO2
3 5678EFGH 1234ABCD
4 1111BBBB 0000AAAA
1 1234ABCD 5678EFGH
2 0000AAAA 1111BBBB
The constraints are if no = no2 in another row skip that row.
So in this sample data the only rows that would be selected should be pair no 3 and 4.
I have tried to merge and inner join with self but I just keep getting all 4 rows back.
I have tried to insert into a table where not exists but again I get 4 rows inserted.
SELECT a.* from PAIRS a
inner join PAIRS b on a.no=b.no2 and a.no2=b.no;
I was thinking maybe selecting distinct number from column 1 and then check those in column 2 but I think that would yield the same four rows.
I may be over thinking this problem and maybe some here can look at this and see where the solution is hiding.
I am currently testing this on MySQL but it should run on SQLServer 2008. I have searched but all the questions didn't seem to match my data set issue.
Taking you at your word, meaning selecting all records where the value of no column does not appear anywhere in no2 column in the same table, try this:
SELECT A.PAIR_NO, A.NO, A.NO2
FROM PAIRS A
LEFT JOIN PAIRS B ON(A.NO = B.NO2)
WHERE B.PAIR_NO IS NULL -- assuming this column is not nullable
Another option is to use NOT EXISTS:
SELECT PAIR_NO, NO, NO2
FROM PAIRS A
WHERE NOT EXISTS(
SELECT 1
FROM PAIRS B
WHERE B.NO2 = A.NO
)
I personally prefer the LEFT JOIN option since it's shorter and more readable.
Both of these statement should work on both MySql and Sql Server.
Okay fellas I want to thank you all for helping, but I think I solved my issue. Took me a second but I believe this is what I am after (SQL Server 2008):
if OBJECT_ID('tempdb..#pairs') is not null drop table #pairs
if OBJECT_ID('tempdb..#pairs_final') is not null drop table #pairs_final
create table #pairs(pair_no int, a_no varchar(17),a_no2 varchar(17))
create table #pairs_final(pair_no int Identity(1,1), a_no varchar(17),a_no2 varchar(17))
insert into #PAIRS values(1,'1234ABCD','5678EFGH');
insert into #PAIRS values(1,'1234ABCD','XXXX9999');
insert into #PAIRS values(2,'0000AAAA','1111BBBB');
insert into #PAIRS values(3,'5678EFGH','1234ABCD');
insert into #PAIRS values(4,'1111BBBB','0000AAAA');
insert into #PAIRS values(1,'XXXX9999','1234ABCD');
insert into #pairs_final
select a.a_no,a.a_no2 from #pairs a
join (
select distinct a_no_p from(
select pair_no,a_no_p,
ROW_NUMBER() over (partition by pair_no order by a_no_p) as RN
from #pairs
unpivot(
a_no_p for clms in (a_no2,a_no)
) as umpvt
) as mypairs
where RN = 1
) as my_pairs on my_pairs.a_no_p=a.a_no
select * from #pairs_final
This will give me the following results:
pair_no a_no a_no2
1 1234ABCD 5678EFGH
2 1234ABCD XXXX9999
3 0000AAAA 1111BBBB
Hope this might help someone else.
Enjoy.
DECLARE #TBL AS TABLE
(
[NO] INT,
[CODE] VARCHAR(50),
[AREA] VARCHAR(50)
)
/* EXAMPLE 1 */
INSERT INTO #TBL([NO],[CODE],[AREA]) VALUES (1,'001','A00')
INSERT INTO #TBL([NO],[CODE],[AREA]) VALUES (2,'001','A00')
INSERT INTO #TBL([NO],[CODE],[AREA]) VALUES (3,'001','B00')
INSERT INTO #TBL([NO],[CODE],[AREA]) VALUES (4,'001','C00')
INSERT INTO #TBL([NO],[CODE],[AREA]) VALUES (5,'001','C00')
INSERT INTO #TBL([NO],[CODE],[AREA]) VALUES (6,'001','A00')
INSERT INTO #TBL([NO],[CODE],[AREA]) VALUES (7,'001','A00')
/* EXAMPLE 2 */
/* ***** USE THIS CODE TO ENTER DATA FROM DIRECT TABLE *****
SELECT
ROW_NUMBER() OVER(ORDER BY [FIELD_DATE]) AS [NO]
,[FIELD_CODE] AS [CODE]
,[FIELD_AREA] AS [AREA]
FROM TABLE_A
WHERE CAST([FIELD_DATE] AS DATE) >= CAST('20200307' AS DATE)
ORDER BY [FIELD_DATE],[FIELD_CODE]
*/
SELECT
A.NO AS ANO
,A.CODE AS ACODE
,A.AREA AS AAREA
,B.NO AS BNO
,B.CODE AS BCODE
,B.AREA AS BAREA
,CASE WHEN A.AREA=B.AREA THEN 'EQUAL' ELSE 'NOT EQUAL' END AS [COMPARE AREA]
FROM #TBL A
LEFT JOIN #TBL B
ON A.NO=B.NO+1

Some problems with INSERT INTO statement

I have this mysql syntax:
INSERT INTO `utilizatori`(
utilizator
)
SELECT
'Mama'
FROM
`utilizatori`
WHERE
NOT EXISTS (SELECT `utilizator` FROM `utilizatori` WHERE utilizator='Mama')
utilizatori is a table, utilizator is a column, Mama is a value
This syntax will insert a value in table only if it doesnt exist.If the value exist it wont create it,so until now it works fine,but if there is no 'Mama' value,then it will insert it...the only problem is that it will insert it multiple times.For example if i have 4 rows,it will insert 'Mama' value 4 times,creating 4 rows.Any idea??
I would make the task easier, clearer by making utilizator field unique.
That way when you add new rows with existing value 'Mama' for utilizator in this case: mysql returns error with the code: 1062, and don't let user have multiple rows with Mama in the table.
So when you run query:
INSERT INTO `utilizatori` (utilizator) VALUES ('Mama')
You can check if MySQL returns any error, but better to check number of affected rows, if insert was successful it will be equal to 1 otherwise 0.
Checking mechanism depends what language and driver you use for connecting to database.
Since you had PHP tag selected you may be using PDO than
$statement->rowCount(); // $statement = PDOStatement, I assume you know this thing well
will give you desired result
Final simple example:
...
if ($statement->rowCount())
{
echo "Cool! You have been added to database";
}
else
{
echo "Hmms! Are you trying to duplicate something?";
}
Try to use group by :
INSERT INTO `utilizatori`(
utilizator
)
SELECT
'Mama'
FROM
`utilizatori`
WHERE
NOT EXISTS (SELECT `utilizator` FROM `utilizatori` WHERE utilizator='Mama')
group by utilizator
You are basically doing:
SELECT ... WHERE NOT EXISTS
...and inserting this in your table. As stated in the comments, just make your utilizator field unique and drop the whole SELECT part from your query.
Where Column is missing...
INSERT INTO `utilizatori`(
utilizator
)
SELECT
'Mama'
FROM
`utilizatori`
WHERE
'Mama'
NOT EXISTS (SELECT `utilizator` FROM `utilizatori` WHERE utilizator='Mama')

INSERT INTO with SubQuery MySQL

I have this Statement:
INSERT INTO qa_costpriceslog (item_code, invoice_code, item_costprice)
VALUES (1, 2, (SELECT item_costprice FROM qa_items WHERE item_code = 1));
I'm trying to insert a value copy the same data of item_costprice, but show me the error:
Error Code: 1136. Column count doesn't match value count at row 1
How i can solve this?
Use numeric literals with aliases inside a SELECT statement. No () are necessary around the SELECT component.
INSERT INTO qa_costpriceslog (item_code, invoice_code, item_costprice)
SELECT
/* Literal number values with column aliases */
1 AS item_code,
2 AS invoice_code,
item_costprice
FROM qa_items
WHERE item_code = 1;
Note that in context of an INSERT INTO...SELECT, the aliases are not actually necessary and you can just SELECT 1, 2, item_costprice, but in a normal SELECT you'll need the aliases to access the columns returned.
You can just simply e.g.
INSERT INTO modulesToSections (fk_moduleId, fk_sectionId, `order`) VALUES
((SELECT id FROM modules WHERE title="Top bar"),0,-100);
I was disappointed at the "all or nothing" answers. I needed (again) to INSERT some data and SELECT an id from an existing table.
INSERT INTO table1 (id_table2, name) VALUES ((SELECT id FROM table2 LIMIT 1), 'Example');
The sub-select on an INSERT query should use parenthesis in addition to the comma as deliminators.
For those having trouble with using a SELECT within an INSERT I recommend testing your SELECT independently first and ensuring that the correct number of columns match for both queries.
Your insert statement contains too many columns on the left-hand side or not enough columns on the right hand side. The part before the VALUES has 7 columns listed, but the second part after VALUES only has 3 columns returned: 1, 2, then the sub-query only returns 1 column.
EDIT: Well, it did before someone modified the query....
As a sidenote to the good answer of Michael Berkowski:
You can also dynamically add fields (or have them prepared if you're working with php skripts) like so:
INSERT INTO table_a(col1, col2, col3)
SELECT
col1,
col2,
CURRENT_TIMESTAMP()
FROM table_B
WHERE b.col1 = a.col1;
If you need to transfer without adding new data, you can use NULL as a placeholder.
If you have multiple string values you want to add, you can put them into a temporary table and then cross join it with the value you want.
-- Create temp table
CREATE TEMPORARY TABLE NewStrings (
NewString VARCHAR(50)
);
-- Populate temp table
INSERT INTO NewStrings (NewString) VALUES ('Hello'), ('World'), ('Hi');
-- Insert desired rows into permanent table
INSERT INTO PermanentTable (OtherID, NewString)
WITH OtherSelect AS (
SELECT OtherID AS OtherID FROM OtherTable WHERE OtherName = 'Other Name'
)
SELECT os.OtherID, ns.NewString
FROM OtherSelect os, NewStrings ns;
This way, you only have to define the strings in one place, and you only have to do the query in one place. If you used subqueries like I initially did and like Elendurwen and John suggest, you have to type the subquery into every row. But using temporary tables and a CTE in this way, you can write the query only once.

How to insert multiple values in a table with an equal second cell

I have s MySQL database and I need to insert some specific data in a table. The data should be as follows:
SELECT id FROM a_table WHERE ... returns me a list of ids.
I need to insert n rows in second_table where n is the count of the returned rows from the first query. The second table requires 2 fields - The first one will be a record from the first query and the second one will be an integer, that I will pass from my script.
For example: If the first query returns (12,14,17,18) and the integer from my script is 5 I need to create a query, that will insert (12,5),(14,5),(17,5),(18,5) and I need this done in the database layer - I don't want to create a select statement, then create a query and then run it.
I need something like this (this is not a real query - It just shows what I need):
INSERT INTO second_table (user_id,group_id) VALUES ((12,14,17,18),5)
or to be more precise like this:
INSERT INTO second_table (user_id,group_id) VALUES ((SELECT id FROM a_table WHERE ...),5)
Is there a way to do this in SQL only (no tsql - sql only)
You can include a literal value in a SELECT:
INSERT INTO second_table (user_id, group_id)
SELECT id, 5
FROM a_table
WHERE ...
INSERT INTO
second_table
(
user_id
,group_id
)
SELECT
id
,5
FROM
first_table
WHERE
...
see the MySQL docs for more details on INSERT...SELECT syntax:
http://dev.mysql.com/doc/refman/5.1/en/insert-select.html
Hi you can try query given below
Insert into items select item_sold_qty , 5 from sales
INSERT INTO second_table
SELECT id , 5 FROM a_table WHERE ...
thanks