are there loops in t-sql ? is using them a good idea? - sql

Pardon me if I'm asking this, but I'm not a SQL Server nor SQL developer.
i have a CSV that i import into a table let's call it T that i create on the fly in SQL Server 2005.
what i would like to do is to run some queries against other tables based on the data imported into the table T i created.
example :
select *
from TableX
where customerID = [this should contain the customerID from the table T]
and then if i find it, i need to update the same table T, if not i move along... until the last record in that csv file. Any idea will be appreciated.

No loop necesary for what you want, it seems that you only need IN:
SELECT *
FROM TableX
WHERE CustomerID IN (SELECT CustomerID FROM TableT)
If you need to update TableX with some mark if exists on TableT, it should be:
UPDATE TableX
SET Mark = 1
WHERE CustomerID IN (SELECT CustomerID FROM TableT)
If you need to update TableX with some value from TableT, it should be something like this:
UPDATE X
SET X.Column = T.Column
FROM TableX X
INNER JOIN TableT T
ON X.CustomerID = T.CustomerID

Looping is a red flag in SQL and is not usually needed. SQL is based on set theory. Understand JOINs and you will rarely need to iterate.
So, in your case, no, looping is neither necessary nor a good idea.

Related

MERGE vs. UPDATE

I was trying to look for it online but couldn't find anything that will settle my doubts.
I want to figure out which one is better to use, when and why?
I know MERGE is usually used for an upsert, but there are some cases that a normal update with with subquery has to select twice from the table(one from a where clause).
E.G.:
MERGE INTO TableA s
USING (SELECT sd.dwh_key,sd.serial_number from TableA#to_devstg sd
where sd.dwh_key = s.dwh_key and sd.serial_number <> s.serial_number) t
ON(s.dwh_key = t.dwh_key)
WHEN MATCHED UPDATE SET s.serial_number = t.serial_number
In my case, i have to update a table with about 200mil records in one enviorment, based on the same table from another enviorment where change has happen on serial_number field. As you can see, it select onces from this huge table.
On the other hand, I can use an UPDATE STATEMENT like this:
UPDATE TableA s
SET s.serial_number = (SELECT t.serial_number
FROM TableA#to_Other t
WHERE t.dwh_serial_key = s.dwh_serial_key)
WHERE EXISTS (SELECT 1
FROM TableA#To_Other t
WHERE t.dwh_serial_key = s.dwh_serial_key
AND t.serial_number <> s.serial_number)
As you can see, this select from the huge table twice now. So, my question is, what is better? why?.. which cases one will be better than the other..
Thanks in advance.
I would first try to load all necessary data from remote DB to the temporary table and then work with that temporary table.
create global temporary table tmp_stage (
dwh_key <your_dwh_key_type#to_devstg>,
serial_number <your_serial_number_type##to_devstg>
) on commit preserve rows;
insert into tmp_stage
select dwh_key, serial_number
from TableA#to_devstg sd
where sd.dwh_key = s.dwh_key;
/* index (PK on dwh_key) your temporary table if necessary ...*/
update (select
src.dwh_key src_key,
tgt.dwh_key tgt_key,
src.serial_number src_serial_number,
tgt.serial_number tgt_serial_number
from tmp_stage src
join TableA tgt
on src.dwh_key = tgt.dwh_key
)
set src_serial_number = tgt_serial_number;

sql query result returns asterisk "*" as column value

I'm trying to update a temporary table with multiple values from another table without using a join.
However, the query doesn't give any error but rather returns an asterisk as the value of the column. I have googled and asked some folks around the office but no one seems to have encountered this before or can offer explanation of why this could be happening.
update ##tempCLUnique set Total =
(
select COUNT(distinct u.unique_subs)
from tbl_Cluster_Cumm_Unique_Subs u
where u.cluster = ##tempCLUnique.cluster
)
Seems simple enough
Result Screen Grabhttp://i.stack.imgur.com/qE0ER.png
Use this
update ##tempCLUnique set Total = U.unique_subs
FROM ##tempCLUnique
INNER JOIN
(
select COUNT(distinct unique_subs)unique_subs
from tbl_Cluster_Cumm_Unique_Subs
)U
ON
u.cluster = ##tempCLUnique.cluster
Change the join according to your use.
Ashutosh

ADO SQL update table with result of group by query

I am trying to update records in an .mdb table with the number of records containing the same value.
The SQL below does not work but I think gives an indication of what I am trying to achieve.
UPDATE table1 AS A
INNER JOIN (SELECT PH_BSP , Count(PH_BSP) AS PHCOUNT FROM table1 GROUP BY PH_BSP) AS B
ON A.PH_BSP=B.PH_BSP
SET A.PH_SORT = B.PHCOUNT;
Any ideas?
If you are doing this in Access, you need to use a domain aggregate function:
UPDATE table1
SET PH_SORT = DCount("PH_BSP","Table1","PH_BSP='" & PH_BSP & "'")
The above assumes that PH_BSP is a text field, drop the single quotes if it is numeric.
Untested, but setting out the statement thusly this should solve your issue
UPDATE A
SET A.PH_SORT = B.PHCOUNT
From table1 AS A
INNER JOIN (SELECT PH_BSP , Count(PH_BSP) AS PHCOUNT FROM table1 GROUP BY PH_BSP) AS B
ON A.PH_BSP=B.PH_BSP
Edit:
Your problem might be from your sub query, I would try putting that part into a separate Access Query and see how it goes. From memory I used to have a lot of trouble with Access and subqueries, square brackets would also sometimes help, but unreliable from memory.
Have you tried something alike?
update table1 as a
set a.ph_sort = (
select COUNT(b.ph_bsp) as phcount
from table1 b
where b.ph_bsp = a.ph_bsp)
I'm assuming SQL Server here.
But this or something alike should do it, I guess.

MS-ACCESS: Deleting all rows except for top 1 and updating a table from a query

I'm almost done with this, just a few last hiccups. I now need to delete all records from a table except for the top 1 where readings_miu_id is the "DISTINCT" column. In other words words i need to delete all records from a table other than the first DISTINCT readings_miu_id. I am assuming all I need to do is modify the basic delete statement:
DELETE FROM analyzedCopy2
WHERE readings_miu_id = some_value
But I can't figure out how to change the some_column=some_value part to something like:
where some_column notequal to (select top 1 from analyzedCopy2 as A
where analyzedCopy2.readings_miu_id = A.readings_miu_id)
and then I need to figure out how to use an UPDATE statement to update a table (analyzedCopy2) from a query (which is where all of the values I want stored into column RSSI in table analyzedCopy2 are currently located). I've tried this:
UPDATE analyzedCopy2 from testQuery3 SET analyzedCopy2.RSSI =
(select AvgOfRSSI from testQuery3 INNER JOIN analyzedCopy2 on analyzedCopy2.readings_miu_id = testQuery3.readings_miu_id where analyzedCopy2.readings_miu_id = testQuery3.readings_miu_id)
where analyzedCopy2.readings_miu_id = testQuery3.readings_miu_id
but apparently I can't use FROM inside of an update statement. Any thoughts?
I'm sure I'm going about this a very nonstandard (and possibly if not probably the flat out wrong) way but I'm not being allowed to use vb.net2008 to pull and manipulate then store the data like I would like to so I'm stuck right now using sql statements in ms-access which is a good learning experience (Even if trying to do such odd things as I've been having to do in sql statements is making me beat my head against my deck figuratively of course)
MS Access UPDATE sql statements cannot reference queries, but they can reference tables. So the thing to do is store the query results into a table.
SELECT YourQuery.*
INTO TempTable1
FROM YourQuery
Now you can use TempTable1 in an UPDATE query:
UPDATE TargetTable
INNER JOIN TempTable1 ON TempTable1.TargetTableId = TargetTable.Id
SET TargetTable.TargetField = TempTable1.SourceField
See my answer to this question.
I don't have a copy of access on this machine, and it's been a few years since I dabbled in access, so I'm taking a wild stab here, but can you do a
delete from analyzedCopy2
where readings_miu_id not in (select top 1 readings_miu_id from analyzedCopy2 order by...)
(you'll need the order by to get the proper top 1 record, order by the id maybe?)
I've got no hope of helping you with the second one without a copy of access. I know how I'd do it in TSQL, but access is a whole different kettle of wtf's :-)
I was trying to make too complicated, since all of the records that i needed to pull had the same information in each field that i needed all i had to do was use:
SELECT DISTINCT readings_miu_id, DateRange, RSSI, ColRSSI, Firmware, CFGDate, FreqCorr, Active, OriginCol, ColID, Ownage, SiteID, PremID, prem_group1, prem_group2
FROM analyzedCopy2
ORDER BY readings_miu_id;
in order to pull the top 1 record per readings_miu_id.

Update Query from a Lookup Query

I have a spreadsheet that I am converting to an Access DB. I have a column of typed out customer names that I want to replace with the appropriate customer number from our accounting system.
I have created a table with the customer info, and a query that shows what ID needs to be inserted into the source data. What I'm looking for is:
UPDATE tblStarting_Data
SET CustomerID=x
WHERE TEMPCustomer=y
Where X and Y come from qryIDPerCustomer.
Can I use a loop? How do I reference another query?
Another possibility in MS Access (object names borrowed from Tomalak answer):
UPDATE tblStarting_Data, qryIDPerCustomer
SET tblStarting_Data.CustomerID=qryIDPerCustomer.CustomerID
WHERE tblStarting_Data.TEMPCustomer=qryIDPerCustomer.CustomerName
I think a JOIN will help you:
UPDATE
tblStarting_Data AS sd
INNER JOIN qryIDPerCustomer AS qc ON sd.TEMPCustomer = qc.CustomerName
SET
sd.CustomerID = qc.CustomerID;
This can be expressed as a correlated sub-query as well (though the join syntax is preferable):
UPDATE
tblStarting_Data
SET
CustomerID = (
SELECT CustomerID
FROM qryIDPerCustomer
WHERE CustomerName = tblStarting_Data.TEMPCustomer
)
No need for a loop, both statements will update all records in tblStarting_Data in one step.