sql server Junction table values saves four times in one upload - tsql

I uploaded a csv file to a dummy table(csv_upload) in sql server 2008. I have to distribute the data to the tables below using a trigger;
Questions Answers Test QAT
--------- --------- ------ -----
Questid Ansid Testid Questid
Question Answers Testname Ansid
Testid
id
StdUsername
The trigger code;
INSERT INTO tbl_answers ( Answer)
select DISTINCT Answer
from tbl_csv_upload
INSERT INTO tbl_questions ( Question )
select DISTINCT Question
from tbl_csv_upload
INSERT INTO tbl_taqa (StdUsername,questid, ansid , testid )
SELECT StdUsername ,q.quest_id,a.ans_id,t.test_id
FROM csv_upload c, questions q, answers a, test t
WHERE c.Question = q.Question
AND c.Answer = a.Answer
AND t.test_id = IDENT_CURRENT('test')
This trigger worked well for the first upload from an asp.net application but on second upload it saves the data 4 time in the QAT table instead of ones but other tables are ok.
Pls i need urgent help.

Probably, you have duplicates of questions and answers in your data. DISTINCT gets rid of duplicates currently present in the upload table, but the next time your are calling your proc they get inserted again since it does not take into account values already present in the table.
Use this to insert the answers:
INSERT
INTO answers (answer)
SELECT answer
FROM tbl_csv_upload
EXCEPT
SELECT answer
FROM answers
and a similar query for questions.

Related

Script to create multiple update and SELECT statements

We have 2 tables renewal_bkp and adhoc_bkp and 1 MV as test_mv1.
I basically want to create a script that will update one row of renewal_bkp and adhoc_bkp and then select the data from the above MV.
This needs to be done in a loop fashion. Below is an
example:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
update renewal_bkp set network_status='provisioned' where msisdn='3234561010240';
update adhoc_bkp set status='provisioned' where msisdn='3234561010240';
select * from test_mv1 where msisdn='3234561010240';
...
...
and so on
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
This same statement needs to get generated 1000 times with different msisdn numbers.
Can you help me to create a script to do so, then manually writing down each statements.
Thanks,
Sandeep
Although it is totally unclear how you are accessing the msisdns, here is a compact version that does all three things in one batch, atomic, with the help of Data-Modifying CTE's:
WITH
ids (id) AS (
VALUES ('3234561010240'), ('...'), ...
),
renewals AS (
UPDATE renewal_bkp SET network_status = 'provisioned'
WHERE msisdn IN (SELECT id FROM ids)
),
adhoc AS (
UPDATE adhoc_bkp SET status = 'provisioned'
WHERE msisdn IN (SELECT id FROM ids)
)
SELECT *
FROM test_mv1
WHERE msisdn IN (SELECT id FROM ids)
Instead of the VALUES clause, you can also put a regular SELECT from a dedicated table, which would make sense if you're going to execute this more often than once or twice a year.

are INTO, FROM an JOIN the only ways to get a table?

I'm currently writing a script which will allow me to input a file (generally .sql) and it'll generate a list of every table that's used in that file. the process is simple as it opened the input file, checks for a substring and if that substring exists outputs the line to the screen.
the substring that being checked is tsql keywords that is indicative of a selected table such as INTO, FROM and JOIN. not being a T-SQL wizard those 3 keywords are the only ones i know of that are used to select a table in a query.
So my question is, in T-SQL are INTO, FROM an JOIN the only ways to get a table? or are these others?
There're many ways to get a table, here're some of them:
DELETE
FROM
INTO
JOIN
MERGE
OBJECT_ID (N'dbo.mytable', N'U') where U is the object type for table.
TABLE, e.g. ALTER TABLE, TRUNCATE TABLE, DROP TABLE
UPDATE
However, by using your script, you'll not only get real tables, but maybe VIEW and temporary table. Here're 2 examples:
-- Example 1
SELECT *
FROM dbo.myview
-- Example 2
WITH tmptable AS
(
SELECT *
FROM mytable
)
SELECT *
FROM tmptable

how to convert my colums data to rows in sql server

I am working on an online exam database in sql server where i have one table with following structure :-
id question option1 option2 option3 option4 option1_image option2_image option3_image option4_image
and i want data in following format
id options option_image
in option column, i want to get all options value and in option_image column i want all images. i am using following query
select id,Options,Option_Image
from Questions
unpivot
(
Options
for col in (option1, option2,option3,option4)
) u
unpivot
(
Option_Image
for img in(option1_image,option2_image,option3_image,option4_image)
) v
But it dosnt work
I don't know if this is good for large amount of record
but you can try this
select ID,option1,option1_img from Questions
union all
select ID,option2,option2_img from Questions
union all
select ID,option3,option3_img from Questions
union all
select ID,option4,option4_img from Questions

Merge SQL to Exclude Duplicate Records So Merge 2nd time Doesn't Fail

I have three tables and only one that I directly control and am doing a MERGE between them. See my abbreviated but working example here (sqlfiddle example).
I am doing a MERGE between table 1 and Table 2 to Table 3. Table 1 has duplicate data which the MERGE (erroneously) can handle on the first run (insert) but fails with this message on the second run (update).
The MERGE statement attempted to UPDATE or DELETE the same row more
than once.
My question is, can the MERGE be written to either use an EXCEPT such as
SELECT AdFull FROM [dbo].[Users] WHERE AdFull IS NOT NULL
EXCEPT
SELECT AdFull FROM [dbo].[Users]
WHERE AdFull IS NOT NULL
GROUP BY AdFull
HAVING COUNT(*) = 1
or a different Join to only show users that are not duplicated? Or even a way to select a specific one of the duplicates?
Answered Questions
MERGE is a working Insert due to the nature of Fiddle. But due (AFAIK) to the stateless nature of fiddle one never sees the error in Fiddle on a second run, because a merge never happens with the data, only inserts.
Ignore Rows: Actually I would eventually like to use an individual duplicate row via divining of one based on a condition. The actual data table I am dealing with away from the fiddle example has more columns and it would be nice to maybe select a specific row in a duplicate set due to a specific condition.
The example doesn't bare it out, but yes the duplicates are due to the computed AdFull column. Think of a system adding a temp employee, that user gets a row. Then the temp employee gets hired on as fulltime, keeps the ad account but then gets another row in the user table. Yes I know it shouldn't happen. So that is how a duplicate comes about.
(Duplicate values Table 3) Table three is a result table that can be cleaned out for any duplicates to start this process afresh.
In your MERGE statement can you do something similar this?
MERGE INTO [dbo].Table3 AS T3
USING
(
SELECT
AdFull,
MAX(StartedOn)
FROM [dbo].Table2 AS [ad]
GROUP BY AdFull
) AS T2
ON (T2.AdFull = T3.AdFull)
WHEN MATCHED THEN UPDATE blah
WHEN NOT MATCHED THEN INSERT blah
Using the MAX aggregate with a GROUP BY should give you only the information from when the temp was hired on. Then if the AdFull matches you can simply UPDATE Table3 with the most recent information and if there is no match then INSERT a new row.
UPDATE: If I fail to mention that MERGE should be used with caution I will take flak from #AaronBertrand.

Create a query to select two columns; (Company, No. of Films) from the database

I have created a database as part of university assignment and I have hit a snag with the question in the title.
More likely I am being asked to find out how many films each company has made. Which suggests to me a group by query. But I have no idea where to begin. It is only a two mark question but the syntax is not clicking in my head.
My schema is:
CREATE TABLE Movie
(movieID CHAR(3) ,
title CHAR(36),
year NUMBER,
company CHAR(50),
totalNoms NUMBER,
awardsWon NUMBER,
DVDPrice NUMBER(5,2),
discountPrice NUMBER(5,2))
There are other tables but at first glance I don't think they are relevant to this question.
I am using sqlplus10
The answer you need comes from three basic SQL concepts, I'll step through them with you. If you need more assistance to create an answer from these hints, let me know and I can try to keep guiding you.
Group By
As you mentioned, SQL offers a GROUP BY function that can help you.
A SQL Query utilizing GROUP BY would look like the following.
SELECT list, fields, aggregate(value)
FROM tablename
--WHERE goes here, if you need to restrict your result set
GROUP BY list, fields
a GROUP BY query can only return fields listed in the group by statement, or aggregate functions acting on each group.
Aggregate Functions
Your homework question also needs an Aggregate function called Count. This is used to count the results returned. A simple query like the following returns the count of all records returned.
SELECT Count(*)
FROM tablename
The two can be combined, allowing you to get the Count of each group in the following way.
SELECT list, fields, count(*)
FROM tablename
GROUP BY list, fields
Column Aliases
Another answer also tried to introduce you to SQL column aliases, but they did not use SQLPLUS syntax.
SELECT Count(*) as count
...
SQLPLUS column alias syntax is shown below.
SELECT Count(*) "count"
...
I'm not going to provide you the SQL, but instead a way to think about it.
What you want to do is select where the company matches and count the total rows returned. That count is the number of films made by the specified company.
Hope that points you in the right direction.
Select company, count(*) AS count
from Movie
group by company
select * group by company won't work in Oracle.