I have two select queries like this:
SELECT COUNT(WARD_id)
FROM IP_Admission
WHERE (Status = 'V' OR Status = 'D') AND WARD_ID = 1
SELECT BED_STRENGTH
FROM Ward_Master
WHERE Ward_ID = 1
Output of the query is
2
6
Now I need answer 4. Any help appreciated.
You may try like this:
declare #a int
declare #b int
SELECT #a = COUNT(WARD_id) FROM IP_Admission WHERE (Status='V' OR Status='D') AND WARD_ID=1
SELECT #b = BED_STRENGTH FROM Ward_Master WHERE Ward_ID=1
select #b - #a
select count(i.ward_id) - w.bed_strength as Diff from
ip_admission i join ward_master w on w.ward_id=i.ward_id
where (status='V' or status='D') and i.ward_id=1
group by w.bed_strength
Try This for all ward ID's
SELECT M.Ward_ID,BED_STRENGTH -COUNT(WARD_id)
FROM IP_Admission A
JOIN Ward_Master M ON A.WARD_ID = M.WARD_ID
WHERE (A.Status='V' OR A.Status='D')
GROUP BY M.Ward_ID
You can use inner join like this. Please let me know if this doesn't work.
create table #Tmp1
(
Ward_Id INT,
Status Char(1)
)
create table #tmp2
(
Ward_Id INT,
BED_STRENGTH INT
)
INSERT INTO #Tmp1 VALUES (1,'V'),(1,'D')
INSERT INTO #tmp2 VALUES (1,6)
SELECT COUNT(WARD_id)
FROM #Tmp1
WHERE (Status='V' OR Status='D') AND WARD_ID=1
SELECT BED_STRENGTH FROM #Tmp2 WHERE Ward_ID=1
SELECT #tmp2.BED_STRENGTH - COUNT(#tmp1.WARD_id)
FROM #Tmp1
INNER JOIN #tmp2 ON #tmp2.Ward_Id = #tmp1.Ward_Id
WHERE (Status='V' OR Status='D') AND #tmp1.WARD_ID=1
GROUP BY #tmp2.BED_STRENGTH
DROP TABLE #Tmp1
DROP TABLE #Tmp2
Since you are pulled these values from two different tables, the best way to do this will to be to join the table on ward id.
SELECT wm.BED_STRENGTH - COUNT(ip.WARD_id)
FROM Ward_Master wm inner join IP_Admission ip
On wm.ward_id = ip.ward_id
WHERE (ip.Status='V' OR ip.Status='D')
Group by wm.BED_STRENGTH
This should work, but it might not depending on the schema. The advantage with this method is that it will find the value for all ward ids.
The simplest solution is:
SELECT (subquery1) - (subquery2)
This will only show the value for the ward id that you specify.
Thanks everyone i solved my query as
SELECT M.Bed_Strength - COUNT(A.WARD_id) as diff
FROM IP_Admission A
JOIN Ward_Master M ON A.WARD_ID = M.WARD_ID
WHERE (A.Status='V' OR A.Status='D') and M.Ward_ID=1 group by M.Bed_Strength;
Related
I've a SELECT which checks a status of active alarms (icinga).
This select joins different tables and until here all ok.
On the result I've as value/column an object_id as well. I would like to add a column to that select that could be empty or not, because, searching that 'object_id' on a different table, I could get a value or not. This accessory table is structured having: object_id, varname, varvalue.
So, i.e., my SELECT returns those values:
`name`, `object_id`, `status`
`Hello`, `123456`, `OK`
I would add the column City that should compared to a table having:
`object_id`, `varname`, `varvalue`
`123456`, `city`, `Rome`
`123456`, `lake`, `Garda`
`789789`, `city`, `Milano`
So that if the second table has object_id = 123456 AND city = Rome the result should be:
`name`, `object_id`, `status`, `city`
`Hello`, `123456`, `OK`, `Rome`
Otherwise the result should be:
`Hello`, `123456`, `OK`, `UNKNOWN`
How to do that?
Hope I've explained it well :-)
Thanks!
* EDIT *
It's better I explain with real example. My query actually is the following:
select icinga_objects.object_id, icinga_objects.name1 as host_name, icinga_objects.name2 as ServiceName, "service" as Type, icinga_servicestatus.last_check as LastCheckTime, icinga_servicestatus.last_hard_state_change as LastStateChange, TIMEDIFF(now(), icinga_servicestatus.last_hard_state_change) AS SinceTime,
CASE
WHEN icinga_servicestatus.current_state = 0 THEN '0'
WHEN icinga_servicestatus.current_state = 1 THEN '2'
WHEN icinga_servicestatus.current_state = 2 THEN '3'
ELSE '3'
END AS state
FROM icinga_objects, icinga_servicestatus, icinga_services WHERE icinga_servicestatus.service_object_id IN
(SELECT service_object_id FROM icinga_services WHERE icinga_services.host_object_id IN
(SELECT host_object_id FROM icinga_hostgroup_members WHERE hostgroup_id IN
(SELECT hostgroup_id FROM icinga_hostgroups WHERE alias = 'MY-HOSTGROUP-TO-FILTER')
)
)
AND icinga_servicestatus.service_object_id NOT IN
(SELECT service_object_id FROM icinga_services WHERE icinga_services.service_object_id IN (
SELECT object_id FROM icinga_objects WHERE icinga_objects.is_active = 1 AND icinga_objects.object_id IN
(SELECT object_id FROM icinga_customvariables WHERE varvalue = '8x5')
)
)
AND icinga_servicestatus.last_check > NOW() - INTERVAL 3 HOUR
AND icinga_servicestatus.state_type = 1
AND icinga_servicestatus.scheduled_downtime_depth = 0
AND icinga_objects.object_id = icinga_services.service_object_id
AND icinga_servicestatus.service_object_id = icinga_services.service_object_id
AND icinga_servicestatus.current_state = 2
AND icinga_servicestatus.problem_has_been_acknowledged = 0
This gives me as result, in example:
`object_id`, `host_name`, `ServiceName`, `Type`, `LastCheckTime`, `LastStateChange`, `SinceTime`, `State`
`123456`, `myHostName`, `myServiceName`, `service`, `2020-04-29 17:19:21`, `2020-04-28 14:50:27`, `26:32:51`, `3`
Here I would like to add the column.
So, now if I search object_id into icinga_customvariables I could find entries, or not. In Example, searching object_id = 123456 I have 4 records, but ONLY one having varname = NAME_IM_SEARCHING and so I need to add to the above result the corresponding of varvalue searching icinga_customvariables.object_id = '123456' AND varname = NAME_IM_SEARCHING. IF there are NO results, then the added cloumn should be UNKNOWN, otherwise the added column should be = icinga_customvariables.varvalue.
How to add it? :-)
You can place your query into a "table expression" so it becomes simpler to join it to the other_table. For example:
select
q.*,
coalesce(o.varvalue, 'UNKNOWN') as city
from (
-- your existing query here
) q
left join other_table o on o.object_id = q.object_id and o.varname = 'city'
EDIT: Joining multiple times
As requested if you need to extract more city names using another column, or if you want to extract against another table altogether, you can add an extra LEFT JOIN. For example:
select
q.*,
coalesce(o.varvalue, 'UNKNOWN') as city,
coalesce(o2.varvalue, 'UNKNOWN') as lake
from (
-- your existing query here
) q
left join other_table o on o.object_id = q.object_id and o.varname = 'city'
left join other_table o2 on o.object_id = q.object_id and o2.varname = 'lake'
I have a table in SQL which will contain multiple rows for one id, as below
accountid Productname
1 GL
1 IP
1 MI
2 GL
2 IP
2 PA
3 MI
3 CP
3 IP
4 GL
4 CP
4 CI
I want to be able to select all accounts which have certain products but not other. For example all that have IP or GL but not MI, using the sample table above this would return accounts 2 and 4.
SELECT ccx_accountidname
FROM (
SELECT ccx_accountidname, ccx_productname
FROM Filteredccx_leadresearch
WHERE ccx_productname IN ('GL','IP')
AND ccx_accountidname IS NOT NULL
) AS T
WHERE ccx_productname NOT IN ('MI')
ORDER BY ccx_accountidname
and
SELECT DISTINCT LR1.ccx_accountidname
FROM Filteredccx_leadresearch LR1
LEFT JOIN Filteredccx_leadresearch LR2 ON LR1.ccx_accountid = LR2.ccx_accountid
AND LR2.ccx_productname IN ('GL', 'IP')
WHERE LR1.ccx_productname NOT IN ('MI')
AND LR1.ccx_accountidname IS NOT NULL
ORDER BY LR1.ccx_accountidname
Both give basically the same results, is there any way this can be done?
Thanks in advance for any help
Could you try this:
SELECT DISTINCT T1.Accountidname FROM TheTableThatContainsAccountnames as T1
JOIN AccountProductsTable as T2 on T1.AccountId=T2.AccountId
WHERE T2.ProductName = 'ProductYouWant'
AND T2.ProductName = 'AnOtherProductYouWant'
According to your post, all you really need is a simple query with the correct and logic. You want all accounts with Product name GL or IP but not in MI. This will do it without any other joins.
SELECT ccx_accountidname
FROM Filteredccx_leadresearch
WHERE
ccx_productname in ('GL','IP')
and ccx_productname not in ('MI')
EDIT
This will get you the account, though I doubt it will work in your overall solution. It's just hard to tell without seeing your complete dataset. This could be done with parameters too.
IF OBJECT_ID('tempdb..#TempTable') IS NOT NULL
DROP TABLE #TempTable
IF OBJECT_ID('tempdb..#TempTableTwo') IS NOT NULL
DROP TABLE #TempTableTwo
create table #TempTable (accountid int, productname char(2))
insert into #TempTable (accountid,productname) values
(1,'GL'),
(1,'IP'),
(1,'MI'),
(2,'GL'),
(2,'IP'),
(2,'MA')
select distinct
t1.accountid,
1 as T
into #TempTableTwo
from
#TempTable t1
where
productname in ('GL','IP')
union all
select distinct
t1.accountid,
-1 as T
from
#TempTable t1
where
productname in ('MI')
select
accountid
from #TempTableTwo
group by accountid
having sum(T) > 0
I might be late for the game, but this should do the trick, if anyone is trying to solve a similar problem. I renamed your table and it's columns:
Filteredccx_leadresearch -> l_search
ccx_accountidname -> a_name
ccx_productname -> p_name
And here's the SQL:
(SELECT DISTINCT t1.a_name
FROM l_search t1
JOIN l_search t2 ON t1.a_name = t2.a_name
WHERE t1.p_name = 'IP'
OR t2.p_name = 'GL')
MINUS
(SELECT DISTINCT t1.a_name
FROM l_search t1
JOIN l_search t2 ON t1.a_name = t2.a_name
WHERE ((t1.p_name = 'IP'OR t1.p_name = 'GL') AND t2.p_name = 'MI')
OR
(t1.p_name = 'MI' AND (t1.p_name = 'IP' OR t1.p_name = 'GL')));
First set:
cross product of table on itself with same IDs, get account IDs which have a product 'IP' or 'GL'.
Second set:
cross product of table on itself with same IDs, get account IDs which have p_name ('IP' OR 'GL') on first cross property AND 'MI' on second.
Also, get those IDs, which have the same but the other way around: p_name 'MI' on first cross property AND ('IP' OR 'GL') on second.
And finally subtract the second from the first.
Here is a simple way to include the accounts that match either IP or GL and exclude those accounts if they have an record for MI without using a subquery.
This is assuming t1 is a table that has unique account numbers in accountid and t2 is the table you have shown above that has accountid and Productname columns.
SELECT DISTINCT
t1.accountid
FROM t1
LEFT JOIN t2 AS t2_match
ON t1.accountid = t2_match.accountid
AND
(
t2_match.Productname = 'IP'
OR t2_match.Productname = 'GL'
)
LEFT JOIN t2 AS t2_not_match
ON t1.accountid = t2_not_match.accountid
AND t2_not_match.Productname = 'MI'
WHERE
t2_match.accountid IS NOT NULL
AND t2_not_match.accountid IS NULL
This is really late, but it might help some one.
I'll focus only on using the columns we have on the table we are shown (won't combine it with other tables we were not given).
Since the only table in the example is not clearly named, I'll call it some_table
SELECT t.accountidname, t.productname
FROM some_table t
WHERE t.productname IN ('GL','IP')
AND t.accountidname NOT IN (
SELECT accountidname
FROM some_table
WHERE productname = 'MI'
);
The idea here is to:
Select all accountid and productname that have productname either GL or IP (3rd line)
Select all accountid that have a productname MI and remove them from the values we already have (4th line onwards)
With this values, filtering or combining it with other tables should be rather trivial.
You might want to replace the SELECT with SELECT DISTINCT if the combinations of accountid and productname could be repeated in the table.
I have old tables
Items(vendorId-FK, ManufacturerId (IS NOT FK)),
Vendors(PK- VendorId int),
Manufacturer(PK-ManufacturerId int)
Need to transfer data to new DB and it works on transferring data from vendor, but from Manufacturer it transfer only 30000 (where oldManufacturerId is not null), and other 5000 is not transferred. Any ideas what I'm doing wrong?
New Table Manufacturer
( OldManufacturerID int,
newManufacturerId Uniqueidentifier default newid(),
ManufacturerName varchar (100),
)
New Table Items
( ...
ItemDescription,
ManufacturerId uniqueidentifier,
VendorId uniqueidentifier
)
INSERT INTO dbo.Item
( ...
ItemDescription,
ManufacturerId ,
VendorId
)
SELECT
...
itemDescription,
m.ManufacturerId ,
v.VendorId
FROM OldSqlDatabase.dbo.tbl_Items i
JOIN NewSqlDatabase.dbo.Vendor v ON ISNULL(i.vendor_id, '') = ISNULL(v.SourceVendorID, '')
JOIN NewSqlDatabase.dbo.Manufacturer m ON ISNULL(i.manufacturer_id, '') = ISNULL(m.SourceManufacturerID, '')
I just transfered a data since this table didn't have any relationships, new manufactureId has default newid(), and this new id i want to use in the new item table
INSERT INTO dbo.Manufacturer
( OldManufacturerID ,
ManufacturerName ,
)
SELECT
manufacturer_id ,
manufacturer_name ,
FROM oldManufacture
You likely need to use a LEFT JOIN the get records where there a no values (null values) on which to join. The LEFT JOIN will allow you to select all records from the first table being specified in the join, even if there are no matching records available in the second table in the join.
This would also allow you to get rid of that ISNULL() stuff in the join definitions as well. Those would perform very poorly, as they would not be able to use indexes.
I would suggest something like:
INSERT INTO dbo.Item
( ...
ItemDescription,
ManufacturerId ,
VendorId
)
SELECT
...
itemDescription,
m.ManufacturerId ,
v.VendorId
FROM OldSqlDatabase.dbo.tbl_Items i
LEFT JOIN NewSqlDatabase.dbo.Vendor v
ON i.vendor_id = v.SourceVendorID
LEFT JOIN NewSqlDatabase.dbo.Manufacturer m
ON i.manufacturer_id = m.SourceManufacturerID
Basically I am trying to execute this query
UPDATE communication_relevance SET score = (SELECT ((ces.EXPERT_SCORE * cirm.CONSUMER_RATING) + (12.5 * scs.SIMILARITY)* (1 - EXP(-0.5 * (cal.TIPS_AMOUNT / AT.AVG_TIPS)) + .15))AS ANSWER_SCORE
FROM COMMUNICATION_RELEVANCE AS cr
JOIN network_communications AS nc
ON cr.COMMUNICATION_ID=nc.COMMUNICATIONS_ID
JOIN consumer_action_log AS cal
ON cr.ACTION_LOG_ID=cal.ACTION_LOG_ID
JOIN communication_interest_mapping AS cim
ON nc.PARENT_COMMUNICATIONS_ID=cim.COMMUNICATION_ID
JOIN consumer_interest_rating_mapping AS cirm
ON cr.CONSUMER_ID=cirm.CONSUMER_ID
AND cim.CONSUMER_INTEREST_EXPERT_ID=cirm.CONSUMER_INTEREST_ID
JOIN consumer_expert_score AS ces
ON nc.SENDER_CONSUMER_ID=ces.CONSUMER_ID
AND cim.CONSUMER_INTEREST_EXPERT_ID=CONSUMER_EXPERT_ID
JOIN survey_customer_similarity AS scs
ON cr.CONSUMER_ID=scs.CONSUMER_ID_2
AND cal.SENDER_CONSUMER_ID=scs.CONSUMER_ID_1
OR cr.CONSUMER_ID=scs.CONSUMER_ID_1
AND cal.SENDER_CONSUMER_ID=scs.CONSUMER_ID_2
CROSS JOIN
(SELECT AVG(TIPS_AMOUNT) AS AVG_TIPS
FROM CONSUMER_ACTION_LOG
JOIN COMMUNICATION_RELEVANCE
ON CONSUMER_ACTION_LOG.SENDER_CONSUMER_ID=COMMUNICATION_RElEVANCE.consumer_id) AT)
;
But I get this error:
Error:1/25/2011 1:03:20 PM 0:00:00.135: Lookup Error - MySQL Database Error: You can't specify target table 'communication_relevance' for update in FROM clause
Any help would be much appreciated!
You an use UPDATE (.. JOIN ..) SET syntax
UPDATE communication_relevance X
JOIN (
SELECT cr.COMMUNICATION_ID, ((ces.EXPERT_SCORE * cirm.CONSUMER_RATING)
+ (12.5 * scs.SIMILARITY)
* (1 - EXP(-0.5 * (cal.TIPS_AMOUNT / AT.AVG_TIPS)) + .15)) AS ANSWER_SCORE
FROM COMMUNICATION_RELEVANCE AS cr
JOIN network_communications AS nc ON cr.COMMUNICATION_ID=nc.COMMUNICATIONS_ID
JOIN consumer_action_log AS cal ON cr.ACTION_LOG_ID=cal.ACTION_LOG_ID
JOIN communication_interest_mapping AS cim ON nc.PARENT_COMMUNICATIONS_ID=cim.COMMUNICATION_ID
JOIN consumer_interest_rating_mapping AS cirm ON cr.CONSUMER_ID=cirm.CONSUMER_ID
AND cim.CONSUMER_INTEREST_EXPERT_ID=cirm.CONSUMER_INTEREST_ID
JOIN consumer_expert_score AS ces ON nc.SENDER_CONSUMER_ID=ces.CONSUMER_ID
AND cim.CONSUMER_INTEREST_EXPERT_ID=CONSUMER_EXPERT_ID
JOIN survey_customer_similarity AS scs ON
cr.CONSUMER_ID=scs.CONSUMER_ID_2 AND cal.SENDER_CONSUMER_ID=scs.CONSUMER_ID_1
OR cr.CONSUMER_ID=scs.CONSUMER_ID_1 AND cal.SENDER_CONSUMER_ID=scs.CONSUMER_ID_2
CROSS JOIN
(
SELECT AVG(L.TIPS_AMOUNT) AS AVG_TIPS
FROM CONSUMER_ACTION_LOG L
JOIN COMMUNICATION_RELEVANCE R ON L.SENDER_CONSUMER_ID=R.consumer_id
) AT
) ON X.COMMUNICATION_ID = AT.COMMUNICATION_ID
SET X.score = AT.ANSWER_SCORE;
As a proof of concept for anyone else reading this, here is a table you can create and try the syntax on
create table user_news(
user_id int, article_id int, article_date timestamp,
primary key(user_id, article_id));
insert into user_news select 1,2,'2010-01-02';
insert into user_news select 1,3,'2010-01-03';
insert into user_news select 1,4,'2010-01-01';
insert into user_news select 2,1,'2010-01-01';
insert into user_news select 2,2,'2010-01-02';
insert into user_news select 2,3,'2010-01-02';
insert into user_news select 2,4,'2010-01-02';
insert into user_news select 4,5,'2010-01-05';
Now run the update (it sets the article_date of all records to the MAX article_date from the same user)
update user_news a
join (
select b.user_id, max(b.article_date) adate
from user_news b
group by b.user_id) c
on a.user_id=c.user_id
set a.article_date = c.adate;
Finally, inspect the contents
select * from user_news;
You would have to use a temporary table if you want to do this.
I'd say it's time to have a think about what you're doing, why, and what the risks are :)
the table name
COMMUNICATION_RELEVANCE
is it caps or typo?
basic database normalization would indicate that having a computed field in a table breaks the rules of normalization....you should just be able to perform this calculation in a query on the fly when you need it. Or create a view that contains the calculated field.
I need to check (from the same table) if there is an association between two events based on date-time.
One set of data will contain the ending date-time of certain events and the other set of data will contain the starting date-time for other events.
If the first event completes before the second event then I would like to link them up.
What I have so far is:
SELECT name as name_A, date-time as end_DTS, id as id_A
FROM tableA WHERE criteria = 1
SELECT name as name_B, date-time as start_DTS, id as id_B
FROM tableA WHERE criteria = 2
Then I join them:
SELECT name_A, name_B, id_A, id_B,
if(start_DTS > end_DTS,'VALID','') as validation_check
FROM tableA
LEFT JOIN tableB ON name_A = name_B
Can I then, based on my validation_check field, run a UPDATE query with the SELECT nested?
You can actually do this one of two ways:
MySQL update join syntax:
UPDATE tableA a
INNER JOIN tableB b ON a.name_a = b.name_b
SET validation_check = if(start_dts > end_dts, 'VALID', '')
-- where clause can go here
ANSI SQL syntax:
UPDATE tableA SET validation_check =
(SELECT if(start_DTS > end_DTS, 'VALID', '') AS validation_check
FROM tableA
INNER JOIN tableB ON name_A = name_B
WHERE id_A = tableA.id_A)
Pick whichever one seems most natural to you.
UPDATE
`table1` AS `dest`,
(
SELECT
*
FROM
`table2`
WHERE
`id` = x
) AS `src`
SET
`dest`.`col1` = `src`.`col1`
WHERE
`dest`.`id` = x
;
Hope this works for you.
Easy in MySQL:
UPDATE users AS U1, users AS U2
SET U1.name_one = U2.name_colX
WHERE U2.user_id = U1.user_id
If somebody is seeking to update data from one database to another no matter which table they are targeting, there must be some criteria to do it.
This one is better and clean for all levels:
UPDATE dbname1.content targetTable
LEFT JOIN dbname2.someothertable sourceTable ON
targetTable.compare_field= sourceTable.compare_field
SET
targetTable.col1 = sourceTable.cola,
targetTable.col2 = sourceTable.colb,
targetTable.col3 = sourceTable.colc,
targetTable.col4 = sourceTable.cold
Traaa! It works great!
With the above understanding, you can modify the set fields and "on" criteria to do your work. You can also perform the checks, then pull the data into the temp table(s) and then run the update using the above syntax replacing your table and column names.
Hope it works, if not let me know. I will write an exact query for you.
UPDATE
receipt_invoices dest,
(
SELECT
`receipt_id`,
CAST((net * 100) / 112 AS DECIMAL (11, 2)) witoutvat
FROM
receipt
WHERE CAST((net * 100) / 112 AS DECIMAL (11, 2)) != total
AND vat_percentage = 12
) src
SET
dest.price = src.witoutvat,
dest.amount = src.witoutvat
WHERE col_tobefixed = 1
AND dest.`receipt_id` = src.receipt_id ;
Hope this will help you in a case where you have to match and update between two tables.
I found this question in looking for my own solution to a very complex join. This is an alternative solution, to a more complex version of the problem, which I thought might be useful.
I needed to populate the product_id field in the activities table, where activities are numbered in a unit, and units are numbered in a level (identified using a string ??N), such that one can identify activities using an SKU ie L1U1A1. Those SKUs are then stored in a different table.
I identified the following to get a list of activity_id vs product_id:-
SELECT a.activity_id, w.product_id
FROM activities a
JOIN units USING(unit_id)
JOIN product_types USING(product_type_id)
JOIN web_products w
ON sku=CONCAT('L',SUBSTR(product_type_code,3), 'U',unit_index, 'A',activity_index)
I found that that was too complex to incorporate into a SELECT within mysql, so I created a temporary table, and joined that with the update statement:-
CREATE TEMPORARY TABLE activity_product_ids AS (<the above select statement>);
UPDATE activities a
JOIN activity_product_ids b
ON a.activity_id=b.activity_id
SET a.product_id=b.product_id;
I hope someone finds this useful
UPDATE [table_name] AS T1,
(SELECT [column_name]
FROM [table_name]
WHERE [column_name] = [value]) AS T2
SET T1.[column_name]=T2.[column_name] + 1
WHERE T1.[column_name] = [value];
You can update values from another table using inner join like this
UPDATE [table1_name] AS t1 INNER JOIN [table2_name] AS t2 ON t1.column1_name] = t2.[column1_name] SET t1.[column2_name] = t2.column2_name];
Follow here to know how to use this query http://www.voidtricks.com/mysql-inner-join-update/
or you can use select as subquery to do this
UPDATE [table_name] SET [column_name] = (SELECT [column_name] FROM [table_name] WHERE [column_name] = [value]) WHERE [column_name] = [value];
query explained in details here http://www.voidtricks.com/mysql-update-from-select/
You can use:
UPDATE Station AS st1, StationOld AS st2
SET st1.already_used = 1
WHERE st1.code = st2.code
For same table,
UPDATE PHA_BILL_SEGMENT AS PHA,
(SELECT BILL_ID, COUNT(REGISTRATION_NUMBER) AS REG
FROM PHA_BILL_SEGMENT
GROUP BY REGISTRATION_NUMBER, BILL_DATE, BILL_AMOUNT
HAVING REG > 1) T
SET PHA.BILL_DATE = PHA.BILL_DATE + 2
WHERE PHA.BILL_ID = T.BILL_ID;
I had an issue with duplicate entries in one table itself. Below is the approaches were working for me. It has also been advocated by #sibaz.
Finally I solved it using the below queries:
The select query is saved in a temp table
IF OBJECT_ID(N'tempdb..#New_format_donor_temp', N'U') IS NOT NULL
DROP TABLE #New_format_donor_temp;
select *
into #New_format_donor_temp
from DONOR_EMPLOYMENTS
where DONOR_ID IN (
1, 2
)
-- Test New_format_donor_temp
-- SELECT *
-- FROM #New_format_donor_temp;
The temp table is joined in the update query.
UPDATE de
SET STATUS_CD=de_new.STATUS_CD, STATUS_REASON_CD=de_new.STATUS_REASON_CD, TYPE_CD=de_new.TYPE_CD
FROM DONOR_EMPLOYMENTS AS de
INNER JOIN #New_format_donor_temp AS de_new ON de_new.EMP_NO = de.EMP_NO
WHERE
de.DONOR_ID IN (
3, 4
)
I not very experienced with SQL please advise any better approach you know.
Above queries are for MySql server.
if you are updating from a complex query. The best thing is create temporary table from the query, then use the temporary table to update as one query.
DROP TABLE IF EXISTS cash_sales_sums;
CREATE TEMPORARY TABLE cash_sales_sums as
SELECT tbl_cash_sales_documents.batch_key, COUNT(DISTINCT tbl_cash_sales_documents.cash_sale_number) no_of_docs,
SUM(tbl_cash_sales_documents.paid_amount) paid_amount, SUM(A.amount - tbl_cash_sales_documents.bonus_amount - tbl_cash_sales_documents.discount_given) amount,
SUM(A.recs) no_of_entries FROM
tbl_cash_sales_documents
RIGHT JOIN(
SELECT
SUM(
tbl_cash_sales_transactions.amount
)amount,
tbl_cash_sales_transactions.cash_sale_document_id,
COUNT(transaction_id)recs
FROM
tbl_cash_sales_transactions
GROUP BY
tbl_cash_sales_transactions.cash_sale_document_id
)A ON A.cash_sale_document_id = tbl_cash_sales_documents.cash_sale_id
GROUP BY
tbl_cash_sales_documents.batch_key
ORDER BY batch_key;
UPDATE tbl_cash_sales_batches SET control_totals = (SELECT amount FROM cash_sales_sums WHERE cash_sales_sums.batch_key = tbl_cash_sales_batches.batch_key LIMIT 1),
expected_number_of_documents = (SELECT no_of_docs FROM cash_sales_sums WHERE cash_sales_sums.batch_key = tbl_cash_sales_batches.batch_key),
computer_number_of_documents = expected_number_of_documents, computer_total_amount = control_totals
WHERE batch_key IN (SELECT batch_key FROM cash_sales_sums);
INSERT INTO all_table
SELECT Orders.OrderID,
Orders.CustomerID,
Orders.Amount,
Orders.ProductID,
Orders.Date,
Customer.CustomerName,
Customer.Address
FROM Orders
JOIN Customer ON Orders.CustomerID=Customer.CustomerID
WHERE Orders.OrderID not in (SELECT OrderID FROM all_table)