SELECT query to return a row from a table with all values set to Null - sql

I need to make a query but get the value in every field empty. Gordon Linoff give me the clue to this need here:
SQL Empty query results
which is:
select t.*
from (select 1 as val
) v left outer join
table t
on 1 = 0;
This query wors perfectly on PostgreSQL but gets an error when trying to execute it in Microsoft Access, it says that 1 = 0 expression is not admitted. How could it be fixed to work on microsoft access?
Regards,

If the table has a numeric primary key column whose values are non-negative then the following query will work in Access. The primary key field is [ID].
SELECT t2.*
FROM
myTable AS t2
RIGHT JOIN
(
SELECT TOP 1 (ID * -1) AS badID
FROM myTable AS t1
) AS rowStubs
ON t2.ID = rowStubs.badID
This was tested with Access 2010.

I am offering this answer here, even though you didn't think it worked in my edit to your original question. What is the problem?
select t.*
from (select max(col) as maxval from table as t
) as v left join
table as t
on v.val < t.col;

You can use the following query, but it would still need a little "manual coding".
EDITS:
Actually, you do not need the SWITCH function. Modified query below.
Removed the reference to Description column from one line. Still, you would need to use a Text column name (such as Description) in the last line of the query.
For example, the following query would work for the Months table:
select Months.*
from Months
RIGHT OUTER JOIN
(select "" as DummyColumn from Months) Blank_Data
ON Months.Description = Blank_Data.DummyColumn; --hardcoded Description column

Related

SQL - Stripping a string and using it in a condition

So I have a SQL query issue given to me which i'm struggling to resolve:
It currently brings back 6710445 rows but i need to apply further conditions based on a particular string field.
SELECT
Table1.ExampleColumn1 -- (ID)
,Table1.ExampleColumn2
,Table2.ExampleColumn3
,Table2.ExampleColumn4
,Table3.ExampleColumn5
,Table3.ExampleColumn6
,Table1.StringField
FROM [Example Database].[dbo].[Table1] AS Table1
INNER JOIN [Example Database].[dbo].[Table2] AS Table2
ON Example = Example
INNER JOIN [Example Database].[dbo].[Table3] AS Table3
ON Example = Example
WHERE Month BETWEEN 201304 AND 201603
AND (Age < 19)
The above 'Table1.StringField' has the following type codes displayed as a string in each the rows: "||J183,Y752,J374,Y752."
I also have a reference table (Call it 'Ref1') with 514 of these codes displayed individually, which has no other fields in the table whatsoever.
So what i need to be able to do is find rows from the query above which has any of values from the 'Ref1' displayed anywhere within 'Table1.StringField' individual rows, and if not to not include that row in the results set.
I tried to strip down the 'StringField' column of the comma's and "||" but it didn't work as well as i hoped and ended up bringing back over 30M rows.
Any ideas on how to do this? Preferably so it's efficient and doesn't make the user wait 10 minutes just to query it?
Maybe this will get you half way there... I also agree with Sean Lange's comment about not storing delimited data to begin with but I'm assuming the OP already knows this. You can also pivot/unpivot this data to achieve this as well. This is probably the most brute force way of doing sort of what you're looking to do.
--DROP TABLE #Table
--DROP TABLE #Ref
CREATE TABLE #Table (Col VARCHAR(MAX))
CREATE TABLE #Ref (Code VARCHAR(10))
INSERT INTO #Table (Col) VALUES ('A123,B234,C345'),('A123'),('C345')
INSERT INTO #Ref (Code) VALUES ('A123'),('B234')
SELECT * FROM #Table
SELECT * FROM #Ref
SELECT DISTINCT t.Col
FROM #Table t
CROSS APPLY (
SELECT CASE WHEN CHARINDEX(r.Code, t.Col) > 0 THEN 1 ELSE 0 END AS [ItsHere] FROM #Ref r) oa
WHERE oa.ItsHere = 1
What you need to do is join your query to the Ref1 table on Table1.StringField = Ref1.Ref_1_value and then exclude the Table1 rows that don't match any Ref_1_value. Like this:
SELECT
Table1.ExampleColumn1 -- (ID)
,Table1.ExampleColumn2
,Table2.ExampleColumn3
,Table2.ExampleColumn4
,Table3.ExampleColumn5
,Table3.ExampleColumn6
,Table1.StringField
FROM [Example Database].[dbo].[Table1] AS Table1
INNER JOIN [Example Database].[dbo].[Table2] AS Table2
ON Example = Example
INNER JOIN [Example Database].[dbo].[Table3] AS Table3
ON Example = Example
INNER JOIN [Example Database].[dbo].[Ref1] as Ref1
ON Table1.StringField = Ref1.Ref_1_value
WHERE Month BETWEEN 201304 AND 201603
AND (Age < 19)
AND Ref1.Ref_1_value is not null

Oracle SQL Update one table column with the value of another table

I have a table A, where there is a column D_DATE with value in the form YYYYMMDD (I am not bothered about the date format). I also happen to have another table B, where there is a column name V_TILL. Now, I want to update the V_TILL column value of table B with the value of D_DATE column in table A which happens to have duplicates as well. Meaning, the inner query can return multiple records from where I form a query to update the table.
I currently have this query written but it throws the error:
ORA-01427: single-row subquery returns more than one row
UPDATE TAB_A t1
SET (V_TILL) = (SELECT TO_DATE(t2.D_DATE,'YYYYMMDD')
FROM B t2
WHERE t1.BR_CODE = t2.BR_CODE
AND t1.BK_CODE = t2.BK_CODE||t2.BR_CODE)
WHERE EXISTS (
SELECT 1
FROM TAB_B t2
WHERE t1.BR_CODE = t2.BR_CODE
AND t1.BK_CODE = t2.BK_CODE||t2.BR_CODE)
PS: BK_CODE IS THE CONCATENATION OF BK_CODE and BR_CODE
Kindly help me as I am stuck in this quagmire! Any help would be appreciated.
If the subquery returns many values which one do you want to use ?
If any you can use rownum <=1;
If you know that there is only one value use distinct
SET (V_TILL) = (SELECT TO_DATE(t2.D_DATE,'YYYYMMDD')
FROM B t2
WHERE t1.BR_CODE = t2.BR_CODE
AND t1.BK_CODE = t2.BK_CODE||t2.BR_CODE AND ROWNUM <=1)
or
SET (V_TILL) = (SELECT DISTINCT TO_DATE(t2.D_DATE,'YYYYMMDD')
FROM B t2
WHERE t1.BR_CODE = t2.BR_CODE
AND t1.BK_CODE = t2.BK_CODE||t2.BR_CODE)
above are workarounds. To do it right you have to analyze why you are getting more than one value. Maybe more sophisticated logic is needed to select the right value.
I got it working with this command:
MERGE INTO TAB_A A
USING TAB_B B
ON (A.BK_CODE = B.BK_CODE || B.BR_CODE
AND A.BR_CODE = B.BR_CODE AND B.BR_DISP_TYPE <> '0'
AND ((B.BK_CODE, B.BR_SUFFIX) IN (SELECT BK_CODE,
MIN(BR_SUFFIX)
FROM TAB_B
GROUP BY BK_CODE)))
As mentioned earlier by many, I was missing an extra condition and got it working, otherwise the above mentioned techniques work very well.
Thanks to all!

Oracle: Accessing parent attribute in subquery

How can I access 'parent' attributes in subqueries.
E.g. if I have the following Minimal Working Example snippet, I expect as output
"1,2:3"
however it fails with
ORA-904, T1.F1 invalid Identifier.
Now I know I can rewrite this complete query to get this working, however reason for asking this is:
Why can't I access the 'outer' attrbute?
How can I access it with less modification and
I want to add a column without modyfing the outer query too much.
MWE:
create table T1(F1 INTEGER);
create table T2(F2 INTEGER,F3 INTEGER);
insert into T1(F1) VALUES(1);
insert into T2(F2,F3) VaLUES(1,2);
insert into T2(F2,F3) VALUES(1,2);
insert into T2(F2,F3) VALUES(1,3);
select T1.F1,
(SELECT LISTAGG(A,':') WITHIN GROUP (ORDER BY A) from (select distinct(F3) as A froM T2 where F2 = T1.F1)) as B
from T1;
1) Why can't I access the 'outer' attribute?
Oracle just allows the subquery to access its direct parent query tables... actually, you're trying to access the main query in a subquery of a subquery.
2) How can I access it with less modification
Your inner most subquery could be removed and you could apply a regex to remove duplicates as following:
select
T1.F1,
(
SELECT REGEXP_REPLACE(
LISTAGG(F3,':') WITHIN GROUP (ORDER BY F3),
'([^:]+):(\1(:|$))+',
'\1\3'
)
from T2
where F2 = T1.F1
) as B
from T1;
This regex finds any non-duplicate token (token = data before a : or before the end of line) and checks the next tokens to find any duplicate, replacing all the match for the first non-duplicate found and the : if it's not the end of line.
3) I want to add a column without modyfing the outer query too much
This way your outer query haven't changed, so you can manage it the way you want.

SQL Sybase Query Strange Behaviour

I've got 2 tables with exactly the same structure in the same Sybase database but they're separate tables.
This query works on one of the 2:
select * from table1 where
QUOTA_FIELD >
(SELECT
count(ACCOUNT) FROM
table1 As t1
where SECTOR = t1.SECTOR
AND
STATUS = 'QUOTA'
)
But for the second table I have to change it to this:
select * from table2 as tref where
QUOTA_FIELD >
(SELECT
count(ACCOUNT) FROM
table2 As t2
where tref.SECTOR = t2.SECTOR
AND
STATUS = 'QUOTA'
)
There's a restriction on where this will execute which means it needs to work like in the first query.
Does anyone have any ideas as to why the first might work as expected and the second wouldn't?
Since I am not yet allowed to comment, here as an answer to the question "does anyone...?":
No. I couldn't find anyone :)
This first query cannot work correctly, since it compares a column with itself (as long as the column names are all normal ASCII characters and not some similar looking UNICODE ones). Please give a proof that the result of this query is in every case the same as of query 2.
Also, the second query would normally be done like that: where SECTOR = tref.SECTOR...
You might be looking for something like this in query #1 :
select * from table1 t2 where
QUOTA_FIELD >
(SELECT
count(ACCOUNT) FROM
table1 As t1
where t2.SECTOR = t1.SECTOR
AND
t1.STATUS = 'QUOTA'
)
This explicitly specifies that the table in subquery is joining with the table in outer query ( co-related subquery ).
If this works, use the same idea in query #2

Return a rowset and set a variable in an "IN" clause in SQL Server

I want use the SQL Server IN operator and also set a variable to a column value. Is this possible?
My code is like this:
DECLARE #SubkindId as tinyint;
SELECT NAME FROM SampleTable001 WHERE
Id in (SELECT Id, #SubkindId = Subkind FROM SampleTable002)
ORDER BY Name;
My issue is: I want to set the #SubkindId variable in the inner select statement.
Can It Be Done?
In SQL Server you can't SELECT a result set and SET variables in the same statement (though you can in MySQL). Sorry. But there may be another way to get what you want. Unfortunately, what you want is not completely clear.
Assuming you want to do a SELECT and at the same time return another value into a variable, you have to handle the issue that your query can return multiple rows, so in that case, which one would you want to return into #SubkindId?
Now, I may have misunderstood, and instead of trying to pull the column value into the variable, you instead want to pull only the row where the SubkindId matches the value already in the variable (though you didn't show assigning a value to it first, so this seems less likely).
Please confirm which is the case and answer the above questions, and I can help you more.
In the meantime, I'll try to give you answers for both scenarios.
First, let me mention that I recommend against using the IN() syntax with a subquery returning a list of IDs. It is poor practice in my opinion because it usually demonstrates that the person doesn't really know how to JOIN properly, and as soon as the query gets a little complicated, not only that person but even the best professional SQL Server query writer can get lost (... WHERE x IN (SELECT ... WHERE y IN (SELECT ... WHERE z NOT IN (...))) which soon leads to a serious case of what!?!?!?!. Just use JOINs, and if required, semi-joins (introduced with an EXISTS clause).
Query and Return a Value
If what you really wanted was to get access to the values that the SELECT statement found while doing its join, it might look something like this:
DECLARE #KindsAndSubkinds TABLE (
Name varchar(100),
SubkindId tinyint
);
INSERT #KindsAndSubkinds
SELECT
T1.Name,
T2.SubkindId
FROM
dbo.SampleTable001 T1
INNER JOIN dbo.SampleTable002 T2
ON T1.Id = T2.Id
SELECT DISTINCT Name
FROM #KindsAndSubkinds
ORDER BY Name;
-- Now you can something with the `SubkindId`s in the #KindsAndSubkinds table variable.
Just Query
If you really were just trying to query rather than return a value, this is what I would recommend:
DECLARE #SubkindId as tinyint;
SET #SubkindId = 5;
SELECT
T1.Name
FROM
dbo.SampleTable001 T1
INNER JOIN dbo.SampleTable002 T2
ON T1.Id = T2.Id
WHERE
T2.Subkind = #SubkindId
ORDER BY
T1.Name;
If there are multiple rows in SampleTable002 but you don't want them in the result set, then:
SELECT
T1.Name
FROM
dbo.SampleTable001 T1
WHERE
EXISTS (
-- This semi-join requires at least one row to exist
-- but doesn't increase the row count
SELECT *
FROM dbo.SampleTable002 T2
WHERE
T1.Id = T2.Id
AND T2.Subkind = #SubkindId
)
ORDER BY
T1.Name;
I hope this helps.
Do it like this:
DECLARE #SubkindId as tinyint
SELECT [NAME]
FROM SampleTable001
WHERE Id in (SELECT Id
from SampleTable002
WHERE Subkind=#SubkindId)
order by [Name]
or by using JOIN
DECLARE #SubkindId as tinyint
SELECT [NAME]
FROM SampleTable001 a
INNER JOIN SampleTable002 b
ON a.id = b.id
WHERE b.Subkind=#SubkindId
order by [Name]