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.
Related
I am Using the below table
The case_id for two rows. If the case Id is same then I would want to fetch the row that has Test_script_type as automation and ignore the manual. How can I achieve it with a SQL query..If there is only manual fetch the manual row. How can I achieve it with a SQL query. The Output would be like :
Help is appreciated. Thanks for your time In-advance
You could adress this with not exists:
select t.*
from mytable t
where
script_type = 'Automation'
or not exists (
select 1
from mytable t1
where
t1.case_id = t.case_id
and t1.script_name <> t.script_name
and t1.script_type = 'Automation'
)
You can also filter with a correlated subquery:
select t.*
from mytable t
where t.script_type = (
select min(t1.script_type) -- This gives priority to 'Automation' against 'Manual'
from mytable t1
where t1.case_id = t.case_id
)
SELECT t1.*
FROM `table` t1
LEFT JOIN `table` t2 ON t1.case_id = t2.case_id AND t1.script_type != t2.script_type
WHERE t1.script_type = 'automation' OR t2.case_id IS NULL
You could do something like the following:
WITH cte AS (
SELECT T1.CASE_ID, T1.SCRIPT_NAME, T1.SCRIPT_TYPE,
COUNT(T1.CASE_ID) OVER (PARTITION BY T1.CASE_ID) AS cnt
FROM table1 T1
)
SELECT cte.CASE_ID, cte.SCRIPT_NAME, cte.SCRIPT_TYPE
FROM cte
WHERE (cte.cnt > 1 AND UPPER(cte.SCRIPT_TYPE) = UPPER('AUTOMATION'))
OR cte.cnt = 1
The WITH statement adds a column counting how many times the case_id value is duplicated, which helps identify the rows you want to work with.
Here is an example of it working with the data you have provided: SQLFiddle
If you are using MSSQL Server, You may try below query -
SELECT *
FROM (SELECT CASE_ID, SCRIPT_NAME, SCRIPT_TYPE, ROW_NUMBER() OVER(PARTITION BY CASE_ID ORDER BY SCRIPT_TYPE) RN
FROM YOUR_TAB) T
WHERE RN = 1
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;
How do we run these types of queries in MySQL?
How to execute these types of queries how we run in MySQL, i.e. update join query?
UPDATE file_master t1,users t2 SET
t1.Status = "cancel",
t1.is_credit_revers=1,
t1.is_credit_reversed=1,
t1.t_reversal=t1.credit,
t2.credit=t1.credit+
(
select sum(t1.credit) from file_master where FileID in(7,6,5)
)
WHERE t1.FileID in(7,6,5)
and t1.CRN=t2.id
and t1.CRN=1 ;
1093 - Table 't1' is specified twice, both as a target for 'UPDATE' and as a separate source for data
MySQL objects to updating a table which is also in a sub query
You can sometimes hide the sub query within another sub query to get around this.
As such try something like this:-
UPDATE file_master t1
INNER JOIN users t2
ON t1.CRN = t2.id
CROSS JOIN
(
SELECT credit_sum
FROM
(
SELECT SUM(credit) AS credit_sum
FROM file_master
WHERE FileID IN(7,6,5)
) t3
) t4
SET t1.Status = "cancel",
t1.is_credit_revers = 1,
t1.is_credit_reversed = 1,
t1.t_reversal = t1.credit,
t2.credit = t1.credit + t4.credit_sum
WHERE t1.FileID in(7,6,5)
AND t1.CRN = 1 ;
In my system I want to get attendance data of employee from the DB, so I wrote a huge SQL query, and it gives me relevant details. But now I need an updated version of particular results. So I don’t know how to put this query within the update statement.
select * from(
select concat('pre:', date) as date,concat('pre:',employee_no) as employee_no,concat('pre:',name_with_initials) as name,concat('pre:',sign_in_at) as sign_in_at,concat('pre:',sign_out_at) as sign_out_at,emp from( SELECT date, present.employee_no,employee_details.name_with_initials,present.sign_in_at, present.sign_out_at,employee_details.employee_no as emp from (
SELECT employee_no,date,sign_in_at,sign_out_at FROM complete_shifts WHERE date = '2013-06-17' UNION ALL
SELECT employee_no,date,sign_in_at,'00:00:00 ' AS sign_out_at FROM incomplete_shifts WHERE date = '2013-06-17' UNION ALL
SELECT employee_no,date,sign_in_at,'00:00:00 ' AS sign_out_at FROM incomplete_shift_records WHERE date = '2013-06-17'
)as present inner join employee_details on present.employee_no = employee_details.employee_no
) as final_present
union all
select concat('ab:',date)as date,concat('ab:',employee_no)as employee_no,concat('ab:',name_with_initials)as name,concat('ab:',sign_in_at)as sign_in_at,concat('ab:',sign_out_at)as sign_out_at, emp from(
select '2013-06-17' AS date,absent.employee_no,employee_details.name_with_initials,'00:00:00'as sign_in_at , '00:00:00' as sign_out_at,employee_details.employee_no as emp from (
select * from ( SELECT employee_details.employee_no FROM employee_details left outer join resigned_emps on
employee_details.employee_no = resigned_emps.employee_no where resigned_emps.date is null or resigned_emps.date>'2013-06-17'
) as available_emps left outer join (
select employee_no from complete_shifts where date = '2013-06-17' union
select employee_no from incomplete_shifts where date = '2013-06-17' union
select employee_no from incomplete_shift_records where date = '2013-06-17'
) as present on available_emps.employee_no = present.employee_no where present.employee_no is null
) as absent inner join employee_details on absent.employee_no = employee_details.employee_no
) as final_absent
)as final left outer join( SELECT leave.employee_no as lv_emp
FROM leave_dates inner join leave on leave_dates.leave_id = leave.leave_id where leave_dates.date = '2013-06-17')as leave_emps
on final.emp = leave_emps.lv_emp;
With such a large query, you should just put the results in a temporary table and update from that.
create temporary table toupdate as
<your query goes here>;
Now you can investigate the data that will be updated, to be sure that it really is ok.
Next you can do the update as a join:
update table_to_update t join
toupdate
on t.key = toupdate.key
set t.col = toupdate.col
Because you don't give the column or table details, this is just the structure of such a solution.
Instead of "select *", use the appropriate unique field to fetch the records to update, ex EmpID. Finally use this result as inner query result to update query.
Example
Update ... set ... where empid in (your select query goes here)
I can't do this in MySQL
UPDATE tableA, tableB
SET tableA.column1 = SUM(tableB.column2)
WHERE tableA.column3 = tableB.column4
GROUP BY tableB.column4
;
Neither can I
UPDATE tableA,
(
SELECT SUM(tableB.column2) sumB, tableB.column4
FROM tableB
GROUP BY tableB.column4
) t1
SET tableA.column1 = sumB
WHERE tableA.column3 = column4
;
Besides it being illegal code, I think you can understand what I tried to do with the queries above. Both of them had the same intent.
How can I do that in MySQL?
This would be one way, if you don't mind using a subquery:
UPDATE tableA
SET column1 = (
SELECT sum(column2)
FROM tableB
WHERE tableA.coumn3 = tableB.column4);