I am inserting two values from one table to another table. One of the inserted values comes from concatenating three column values.
I am using the below query, but the error says "subquery has more than one value."
We can't include "top 1" into sub query which gives same value to all.
insert into dbo.tblCrucibleLdgDtls (R2IGTNo,TotalMtrlWgt)
Select R2IGTNo,
(select RTRIM(LTRIM(( CONCAT(ULTotalS1S2MtrlWgt,ULTotalS3S4MtrlWgt,ULTotalS5S6MtrlWgt)))) as TotalMtrlWgt
from dbo.tbl1RMWeighingDetails
where ULTotalS1S2MtrlWgt is not null or ULTotalS3S4MtrlWgt is not null or ULTotalS5S6MtrlWgt is not null
)
from dbo.tbl1RMWeighingDetails
where R2IGTNo like '%C%'
From Table
Solution may be simple. I am not a expert.There is no duplicates and (ULTotalS1S2MtrlWgt,ULTotalS3S4MtrlWgt,ULTotalS5S6MtrlWgt) has unique relation with R2IGTNo. Like if R2IGTNo has b1 then ULTotalS1S2MtrlWgt has value, if R2IGTNo has b2 then ULTotalS3S4MtrlWgt has value, if R2IGTNo has b3 then ULTotalS5S6MtrlWgt has value. with that condition query can be altered.
pls suggest.
Give alias names to the tables:
SELECT ..., (SELECT ... FROM dbo.tbl1RMWeighingDetails wdA)
FROM dbo.tbl1RMWeighingDetails wdB
...
Now the inner/nested sub query can reference wdB, and it will mean the outer instance of the table.
But also, this has the look of something that would be better done with a JOIN, APPLY, or windowing function.
The solution depends on what type of rows you are getting from the inner query. If your inner query returns multiple duplicate rows then the solution is simpler, just use a distinct -
insert into dbo.tblCrucibleLdgDtls (R2IGTNo,TotalMtrlWgt)
Select R2IGTNo,
(select distinct RTRIM(LTRIM((CONCAT(ULTotalS1S2MtrlWgt,ULTotalS3S4MtrlWgt,ULTotalS5S6MtrlWgt)))) as TotalMtrlWgt
from dbo.tbl1RMWeighingDetails
where ULTotalS1S2MtrlWgt is not null or ULTotalS3S4MtrlWgt is not null or ULTotalS5S6MtrlWgt is not null
)
from dbo.tbl1RMWeighingDetails
where R2IGTNo like '%C%'
But if your inner query returns multiple rows which are different from one another then you have to revisit your requirement.
I got the answer by using cte, suggestion got in MS forum
insert into dbo.tblCrucibleLdgDtls (R2IGTNo,TotalMtrlWgt)
Select R2IGTNo, coalesce(ULTotalS1S2MtrlWgt,ULTotalS3S4MtrlWgt,ULTotalS5S6MtrlWgt) as TotalMtrlWgt from dbo.tbl1RMWeighingDetails where R2IGTNo like '%C%'
or
with cte1 as(
select R2IGTNo,RTRIM(LTRIM(( CONCAT(ULTotalS1S2MtrlWgt,ULTotalS3S4MtrlWgt,ULTotalS5S6MtrlWgt)))) as TotalMtrlWgt
from dbo.tbl1RMWeighingDetails
where R2IGTNo like '%C%'
and (ULTotalS1S2MtrlWgt is not null
or ULTotalS3S4MtrlWgt is not null
or ULTotalS5S6MtrlWgt is not null))
insert into dbo.tblCrucibleLdgDtls (R2IGTNo,TotalMtrlWgt)
select * from cte1
Anyway Thank you all. -shankar
Related
Basically, i have a table that have a series of columns named:
ATTRIBUTE10, ATTRIBUTE11, ATTRIBUTE12 ... ATTRIBUTE50
I want a query that gives me all the columns from ATTRIBUTE10 to ATTRIBUTE50 not null
As others have commented we aren't exactly sure of your requirements, but if you want a list the UNPIVOT can do that...
SELECT attribute , value
FROM
(SELECT * from YourFile) p
UNPIVOT
(value FOR attribute IN
(attribute1, attribute2, attribute3, etc.)
)AS unpvt
May be you can use where condition for all columns Or use between operator as below.
For All Columns
where ATTRIBUTE10 is not null and ATTRIBUTE11 is not null ...... and ATTRIBUTE50 is not null
By using between operator
where ATTRIBUTE10 between ATTRIBUTE11 and ATTRIBUTE50
One way to approach the problem is to unfold your table-with-a-zillion-like-named-attributes into one in which you've got one attribute per row, with appropriate foreign keys back to the original table. So something like:
CREATE TABLE ATTR_TABLE AS
SELECT ID_ATTR, ID_TABLE_WITH_ATTRS, ATTR
FROM (SELECT ((ID_TABLE_WITH_ATTRS-1)*100)+1 AS ID_ATTR, ID_TABLE_WITH_ATTRS, ATTRIBUTE10 AS ATTR FROM TABLE_WITH_ATTRS UNION ALL
SELECT ((ID_TABLE_WITH_ATTRS-1)*100)+2, ID_TABLE_WITH_ATTRS, ATTRIBUTE11 FROM TABLE_WITH_ATTRS UNION ALL
SELECT ((ID_TABLE_WITH_ATTRS-1)*100)+3, ID_TABLE_WITH_ATTRS, ATTRIBUTE12 FROM TABLE_WITH_ATTRS);
This only unfolds ATTRIBUTE10, ATTRIBUTE11, and ATTRIBUTE12, but you should be able to get the idea - the rest of the attributes just requires a little cut-n-paste on your part.
You can then query this table to find your non-NULL attributes as
SELECT *
FROM ATTR_TABLE
WHERE ATTR IS NOT NULL
ORDER BY ID_ATTR
Hopefully the difficulty you're encountering in dealing with this table-with-a-zillion-repeated-fields teaches you a hard lesson about exactly why tables with repeated fields or groups of fields are a Bad Idea.
dbfiddle here
I'm trying to clean up some data in SQL server and add a foreign key between the two tables.
I have a large quantity of orphaned rows in one of the tables that I would like to delete. I don't know why the following query would return 0 rows in MS SQL server.
--This Query returns no Rows
select * from tbl_A where ID not in ( select distinct ID from tbl_B
)
When I include IS NOT NULL in the subquery I get the results that I expect.
-- Rows are returned that contain all of the records in tbl_A but Not in tbl_B
select * from tbl_A where ID not in ( select distinct ID from tbl_B
where ID is not null )
The ID column is nullable and does contain null values. IF I run just the subquery I get the exact same results except the first query returns one extra NULL row as expected.
This is the expected behavior of the NOT IN subquery. When a subquery returns a single null value NOT IN will not match any rows.
If you don't exclusively want to do a null check, then you will want to use NOT EXISTS:
select *
from tbl_A A
where not exists (select distinct ID
from tbl_B b
where a.id = b.id)
As to why the NOT IN is causing issues, here are some posts that discuss it:
NOT IN vs. NOT EXISTS vs. LEFT JOIN / IS NULL
NOT EXISTS vs NOT IN
What's the difference between NOT EXISTS vs. NOT IN vs. LEFT JOIN WHERE IS NULL?
Matching on NULL with equals (=) will return NULL or UNKNOWN as opposed to true/false from a logic standpoint. E.g. see http://msdn.microsoft.com/en-us/library/aa196339(v=sql.80).aspx for discussion.
If you want to include finding NULL values in table A where there is no NULL in table B (if B is the "parent" and A is the "child" in the "foreign key" relationship you desire) then you would need a second statement, something like the following. Also I would recommend qualifying the ID field with a table prefix or alias since the field names are the same in both tables. Finally, I would not recommend having NULL values as the key. But in any case:
select * from tbl_A as A where (A.ID not in ( select distinct B.ID from tbl_B as B ))
or (A.ID is NULL and not exists(select * from tbl_B as B where B.ID is null))
The problem is the non-comparability of nulls. If you are asking "not in" and there are nulls in the subquery it cannot say that anything anything is definitely not in becuase it is looking at those nulls as "unknown" and so the answer is always "unknown" in the three value logic that SQL uses.
Now of course that is all assuming you have ANSI_NULLS ON (which is the default) If you turn that off then suddenly NULLS become comparable and it will give you results, and probably the results you expect.
If the ids are never negative, you might consider something like:
select *
from tbl_A
where coalesce(ID, -1) not in ( select distinct coalesce(ID, -1) from tbl_B )
(Or if id is a string, use something line coalesce(id, '<null>')).
This may not work in all cases, but it has the virtue of simplicity on the coding level.
You probably have ANSI NULLs switched off. This compares null values so null=null will return true.
Prefix the first query with
SET ANSI_NULLS ON
GO
I'd like to achieve something as follows, I have the following query (As simple as this),
SELECT ENT_ID,TP_ID FROM TC_LOGS WHERE ENT_ID IN (1,2,3,4,5).
Now the table TC_LOGS may not have all the items in the IN clause. So assuming that the table TC_LOGS has only 1,2. I'd like to compare the items in the IN clause i.e. 1,2,3,4,5 with 1,2(the resultset) and get a result as FOUND - 1,2 NOT FOUND - 3,4,5. I've have implemented this by applying an XSL transformation on the resultset in the application code, but I'd like to achieve this in a query, which I feel is more of an elegant solution to this problem. Also, I tried the following query with NVL, just to separate out the FOUND and NOT FOUND items as,
SELECT NVL(ENT_ID,"NOT FOUND") FROM TC_LOGS WHERE ENT_ID IN(1,2,3,4,5)
I was expecting a result as 1,2,NOT FOUND,NOT FOUND,NOT FOUND
But the above query doesn't return any result.. I'd appreciate if someone can guide me in the right path here.. Thanks much in advance.
Assuming that the items in your IN list can (or can come) from another query, you can do something like
WITH src AS (
SELECT level id
FROM dual
CONNECT BY level <= 5)
SELECT nvl(ent_id, 'Not Found' )
FROM src
LEFT OUTER JOIN tc_logs ON (src.id = tc_logs.ent_id)
In my case, the src query is just generating the numbers 1 through 5. You could just as easily fetch that data from a different table, load the numbers into a collection that you query using the TABLE operator, load the numbers into a temporary table that you query, etc. depending on how the IN list data is determined.
NVL isn't going to work because no values (including NULLS) are returned when there is no match with the IN statement.
What you can do is something like this:
SELECT NVL(ENT_ID, "NOT FOUND")
FROM TC_LOGS
RIGHT OUTER JOIN (
SELECT 1 AS 'TempID' UNION
SELECT 2 UNION
SELECT 3 UNION
SELECT 4 UNION
SELECT 5) AS Sub ON ENT_ID = TempID
The outer join will return NULLS for ENT_ID where there are no matches. Note, I'm not an Oracle person so I can't guarantee that this syntax is perfect.
if you have a table (let's use table src )contains all (1,2,3,4,5) values, you can use full join.
You can use (WITH src AS ( SELECT level id FROM dual CONNECT BY level <= 5) as the src table also)
SELECT
ent_id,tl.tp_id,src.tp_id
FROM
src
FULL JOIN
tc_logs tl
USING (ent_id)
ORDER BY
ent_id
Here is the web site for oracle full join.http://psoug.org/snippet/Oracle-PL-SQL-ANSI-Joins-FULL-JOIN_738.htm
I am trying to construct a single SQL statement that returns unique, non-null values from multiple columns all located in the same table.
SELECT distinct tbl_data.code_1 FROM tbl_data
WHERE tbl_data.code_1 is not null
UNION
SELECT tbl_data.code_2 FROM tbl_data
WHERE tbl_data.code_2 is not null;
For example, tbl_data is as follows:
id code_1 code_2
--- -------- ----------
1 AB BC
2 BC
3 DE EF
4 BC
For the above table, the SQL query should return all unique non-null values from the two columns, namely: AB, BC, DE, EF.
I'm fairly new to SQL. My statement above works, but is there a cleaner way to write this SQL statement, since the columns are from the same table?
It's better to include code in your question, rather than ambiguous text data, so that we are all working with the same data. Here is the sample schema and data I have assumed:
CREATE TABLE tbl_data (
id INT NOT NULL,
code_1 CHAR(2),
code_2 CHAR(2)
);
INSERT INTO tbl_data (
id,
code_1,
code_2
)
VALUES
(1, 'AB', 'BC'),
(2, 'BC', NULL),
(3, 'DE', 'EF'),
(4, NULL, 'BC');
As Blorgbeard commented, the DISTINCT clause in your solution is unnecessary because the UNION operator eliminates duplicate rows. There is a UNION ALL operator that does not elimiate duplicates, but it is not appropriate here.
Rewriting your query without the DISTINCT clause is a fine solution to this problem:
SELECT code_1
FROM tbl_data
WHERE code_1 IS NOT NULL
UNION
SELECT code_2
FROM tbl_data
WHERE code_2 IS NOT NULL;
It doesn't matter that the two columns are in the same table. The solution would be the same even if the columns were in different tables.
If you don't like the redundancy of specifying the same filter clause twice, you can encapsulate the union query in a virtual table before filtering that:
SELECT code
FROM (
SELECT code_1
FROM tbl_data
UNION
SELECT code_2
FROM tbl_data
) AS DistinctCodes (code)
WHERE code IS NOT NULL;
I find the syntax of the second more ugly, but it is logically neater. But which one performs better?
I created a sqlfiddle that demonstrates that the query optimizer of SQL Server 2005 produces the same execution plan for the two different queries:
If SQL Server generates the same execution plan for two queries, then they are practically as well as logically equivalent.
Compare the above to the execution plan for the query in your question:
The DISTINCT clause makes SQL Server 2005 perform a redundant sort operation, because the query optimizer does not know that any duplicates filtered out by the DISTINCT in the first query would be filtered out by the UNION later anyway.
This query is logically equivalent to the other two, but the redundant operation makes it less efficient. On a large data set, I would expect your query to take longer to return a result set than the two here. Don't take my word for it; experiment in your own environment to be sure!
try something like SubQuery:
SELECT derivedtable.NewColumn
FROM
(
SELECT code_1 as NewColumn FROM tbl_data
UNION
SELECT code_2 as NewColumn FROM tbl_data
) derivedtable
WHERE derivedtable.NewColumn IS NOT NULL
The UNION already returns DISTINCT values from the combined query.
Union is applied wherever the row data required is similar in terms of type, values etc. It doesnt matter you have column in the same table or the other to retrieve from as the results would remain the same ( in one of the above answers already mentioned though).
As you didn't wanted duplicates theres no point using UNION ALL and use of distinct is simply unnecessary as union gives distinct data
Can create a view would be best choice as view is a virtual representation of the table. Modifications could be then done neatly on that view created
Create VIEW getData AS
(
SELECT distinct tbl_data.code_1
FROM tbl_data
WHERE tbl_data.code_1 is not null
UNION
SELECT tbl_data.code_2
FROM tbl_data
WHERE tbl_data.code_2 is not null
);
Try this if you have more than two Columns:
CREATE TABLE #temptable (Name1 VARCHAR(25),Name2 VARCHAR(25))
INSERT INTO #temptable(Name1, Name2)
VALUES('JON', 'Harry'), ('JON', 'JON'), ('Sam','harry')
SELECT t.Name1+','+t.Name2 Names INTO #t FROM #temptable AS tSELECT DISTINCT ss.value FROM #t AS t
CROSS APPLY STRING_SPLIT(T.Names,',') AS ss
Consider a table A. Table A has a column named INNETTEDTXNID which is not the Primary key and neither unique and can be null.
I have a select * on table A based on some condition(not related to column INNETTEDTXNID).
For each of the rows fetched above i have to find a value called isNetted. The concept of isNetted is that if the column INNETTEDTXNID of this row is present more than once in the entire table(including this row) then the value of isNetted would be true for this row.
I hope my question is clear. Thanks for advance in help.
This will return the values of any entries that appear more than once.
SELECT a.INNETTEDTXNID
FROM TableA as a, TableA as b
WHERE
not a.id=b.id
and a.INNETTEDTXNID=b.INNETTEDTXNID
if your trying to do this specifically to check if a single number appears more than once you could do something like
SELECT COUNT(INNETTEDTXNID)
FROM TableA
WHERE INNETTEDTXNID='value'
if it returns one, then its unique, for more than one its not unique. IF you want it to return something like true or false you could use
SELECT
CASE WHEN (
SELECT COUNT(INNETTEDTXNID)
FROM TableA
WHERE INNETTEDTXNID='value'
)>1 THEN 'True'
ELSE 'False'
END
AS isNetted
Probably no-where near the most efficient but it works.
SELECT TableA.INNETTEDTXNID,
CASE
WHEN NetChk.INNETTEDTXNID IS NOT NULL Then 1
ELSE 0
END AS isNetted
FROM TABLEA
LEFT JOIN (
SELECT INNETTEDTXNID
FROM TableA
GROUP BY INNETTEDTXNID
HAVING COUNT(INNETTEDTXNID) >1)
NetChk ON TableA.INNETTEDTXNID = NetChk.INNETTEDTXNID