SQL Server Join - With INFO_SCHEMA information - sql

I have the first table:
select COLUMN_NAME
from Emerald_Data.INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = N'tbl_Client_List_Pricing'
Don't mind the numbering in the Column_Name. I was doing this while testing because I need the order to remain as they are in the table. Not by ASC, DESC.
Anyhow, I don't know how to use the row numbers on the left that the system provides to JOIN another table without a condition.
Here is Table 2:
You can see that the left row numbers are my linking value but I don't know how to use that system index value as a condition in my JOIN.
Or if there is another way to join these two tables without a condition while keeping the Table 1 information in it's correct position and not affecting it by ORDER would be much appreciated.
Thank you!
-Chase

I guess you are looking for row_number. Use row_number to order result of two queries then join by matching order nums. Your query would be something like
with query_1 as (
select COLUMN_NAME
, rn = row_number() over (order by cast(left(COLUMN_NAME, 3) as int))
from Emerald_Data.INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = N'tbl_Client_List_Pricing'
)
, query_2 as (
select
*, rn = row_number() over (order by (select null))
from
Table_2
)
select
*
from
query_1 q1
join query_2 q2 on q1.rn = q2.rn

select COLUMN_NAME from Emerald_Data.INFORMATION_SCHEMA.COLUMNS
inner join with Table_2 on Num=cast(LEFT(COLUMN_NAME,CHARINDEX('-', COLUMN_NAME)) AS int)
where TABLE_NAME = N'tbl_Client_List_Pricing'

You could also use sys.all_columns object which could able to state the index for your desired column & JOIN them with table2
SELECT *
FROM sys.all_columns c
INNER JOIN Table2 t ON t.Num = c.column_id
WHERE OBJECT_NAME(object_id) = 'tbl_Client_List_Pricing'

Related

Oracle 11G DB : Result from 'clob' type column in view changed while using the view in a where clause

I have the current query that i'm running in Oracle:
WITH viewa
AS (SELECT c.columna
FROM sometable c
LEFT JOIN othertable u
ON ( c.id = u.id )
WHERE id= '111'
ORDER BY c.created_date)
SELECT columna
FROM (SELECT rownum AS row_num,
t.*
FROM viewa t)
WHERE row_num > (SELECT CASE
WHEN ( Count(*) > 100 ) THEN Count(*) - 100
ELSE 0
END AS num
FROM viewa)
the idea is to always get the first 100 rows.
as you can see, i'm creating a view at the beginning and use it twice:
in the from and in the where.
i'm doing that so i wouldn't need to fetch the first select twice and it also make the query more readable.
notice that columna is of type CLOB!!
when i'm doing the same query with other column types its working!
so its probably something related to the clob column
The weird think is that the results that im getting are empty values even though i have values in the DB!
when i'm removing the subselect in the where i'm getting the right result:
WITH viewa
AS (SELECT c.columna
FROM sometable c
LEFT JOIN othertable u
ON ( c.id = u.id )
WHERE id = '111'
ORDER BY c.created_date)
SELECT columna
FROM (SELECT rownum AS row_num,
t.*
FROM viewa t)
WHERE row_num > 0
seems like Oracle is turning the values for the Clob column "columnA" into null when using the view in the where.
is someone familiar with that?
know how to go around it ?
i solved it with a different query but i still would like to know if Oracle does change the view while fetching from it?
thank you
Without sample data this is hard but I'm guessing the reason is you're depending on rownum. Use the FETCH clause instead to limit the number of rows.
WITH viewa
AS (SELECT c.columna
FROM sometable c
LEFT JOIN othertable u ON ( c.id = u.id )
-- an order by clause should go here
FETCH FIRST 100 ROWS ONLY)
SELECT columna
FROM viewa
But you don't need that CTE at all, just do
SELECT c.columna
FROM sometable c
LEFT JOIN othertable u ON ( c.id = u.id )
-- an order by clause should go here
FETCH FIRST 100 ROWS ONLY
Note that the "first" rows are not guaranteed to be a specific set of rows unless you explicitly add an ORDER BY clause.
Since 11g does not have FETCH FIRST, you can just use rownumber as the limiting criteria. See Example at Oracle Live
select columna, created_date
from (
select c.columna, c.created_date
from sometable c
left join othertable u
on ( c.id = u.id )
where c.id = '111'
order by c.created_date
)
where rownum <= 10;

getting distinct value with all column sqlserver

select
distinct TagName as new, *,(REPLACE(TagName,' ','-')) as SeoProduct_Name
from
dbo.tbl_Image_Master
inner join
dbo.tbl_size
on tbl_size.Size_Id=tbl_Image_Master.Size_Id
inner join
tbl_category
on tbl_category.Cat_Id = tbl_Image_Master.Cat_Id
I want to select distinct tag name with all column
SELECT * FROM TBL WHERE TAGNAME IN (
SELECT DISTINCT TAGNAME FROM TBL)
OR
SELECT * FROM (
SELECT *,ROW_NUMBER() OVER (PARTITION BY TAGNAME ORDER BY (SELECT 1)) AS ROWNUM FROM TBL WHERE TAGNAME)
WHERE ROWNUM =1
Hope it solves the Purpose !!!
If you want to get all columns from a table in a query you can use this syntax :
TableName.*
Example :
Select Table1.Col1, Table1.* from Table1;
I would post what your query becomes, but I am not sure what table you want all columns from.
In the distinct query you cannot select all the columns you need because if you do so you are going to get multiple values that you don't need.
So what you can do is to use you query inside another query, as for example
SELECT TagName AS new, *,(REPLACE(TagName,' ','-')) AS SeoProduct_Name,
<other_colums_you_need>
FROM <table>
WHERE ItemID IN (
SELECT DISTINCT TagName <replaceWithSomeID>
FROM dbo.tbl_Image_Master
INNER JOIN dbo.tbl_size
ON tbl_size.Size_Id=tbl_Image_Master.Size_Id
INNER JOIN tbl_category
ON tbl_category.Cat_Id = tbl_Image_Master.Cat_Id
)
Remember that the values that you require (rows) need to have an unique identifier or ID column, so make sure to return in the subquery that unique ID of the values you need. So you are only going to get the info you require.

SQL Server ROW_NUMBER Left Join + when you don't know column names

I'm writing a page that will create a query (for non-db users) and it create the query and run it returning the results for them.
I am using row_number to handle custom pagination.
How do I do a left join and a row_number in a subquery when I don't know the specific columns I need to return. I tried to use * but I get an error that
The column '' was specified multiple times
Here is the query I tried:
SELECT * FROM
(SELECT ROW_NUMBER() OVER (ORDER BY Test) AS ROW_NUMBER, *
FROM table1 a
LEFT JOIN table2 b
ON a.ID = b.ID) x
WHERE ROW_NUMBER BETWEEN 1 AND 50
Your query is going to fail in SQL Server regardless of the row_number() call. The * returns all columns, including a.id and b.id. These both have the same name. This is fine for a query, but for a subquery, all columns need distinct names.
You can use row_number() for an arbitrary ordering by using a "subquery with constant" in the order by clause:
SELECT * FROM
(SELECT ROW_NUMBER() OVER (ORDER BY (select NULL)) AS ROW_NUMBER, *
FROM table1 a
LEFT JOIN table2 b
ON a.ID = b.ID) x
WHERE ROW_NUMBER BETWEEN 1 AND 50 ;
This removes the dependency on the underlying column name (assuming none are named ROW_NUMBER).
Try this sql. It should work.
SELECT * FROM
(SELECT ROW_NUMBER() OVER (ORDER BY a.Test) AS ROW_NUMBER, a.*,b.*
FROM table1 a
LEFT JOIN table2 b
ON a.ID = b.ID) x
WHERE ROW_NUMBER BETWEEN 1 AND 50

Where Statement w/ Distinct

I have a large table but for the purposes of this question, let's assume I have the follwoing column strucure:
I'd like to have a Where statement that returns only rows where the e-mail address is distinct in that particular column.
Thoughts?
SELECT BillingEMail
FROM tableName
GROUP BY BillingEMail
HAVING COUNT(BillingEMail) = 1
OR HAVING COUNT(*) = 1
SQLFiddle Demo
I don't know what RDBMS you are using (the reason why i can't introduce of using analytical functions) but you can do this by joining with a subquery if you want to get all columns
SELECT a.*
FROM tableName a
INNER JOIN
(
SELECT BillingEMail
FROM tableName
GROUP BY BillingEMail
HAVING COUNT(BillingEMail) = 1
)b ON a.BillingEMail = b.BillingEMail
SQLFIddle Demo
In most databases, you can do this
select t.AccountId, t.BillingEmail
from (select t.*, count(*) over (partition by BillingEmail) as cnt
from t
) t
where cnt = 1
The advantage of this approach is that you can get as many columns as you like from the table.
I prefer JW's approach, but here is another one using NOT EXISTS.
SELECT AccountID, [Billing Email]
FROM table t1
WHERE NOT EXISTS (
-- Make sure that no other row contains the same
-- email, but a different Account ID.
SELECT 1
FROM table t2
WHERE t1.[Billing Email] = t2.[Billing Email]
AND t1.AccountID <> t2.AccountID
)

SQL - using a value in a nested select

Hope the title makes some kind of sense - I'd basically like to do a nested select, based on a value in the original select, like so:
SELECT MAX(iteration) AS maxiteration,
(SELECT column
FROM table
WHERE id = 223652
AND iteration = maxiteration)
FROM table
WHERE id = 223652;
I get an ORA-00904 invalid identifier error.
Would really appreciate any advice on how to return this value, thanks!
It looks like this should be rewritten with a where clause:
select iteration,
col
from tbl
where id = 223652
and iteration = (select max(iteration) from tbl where id = 223652);
You can circumvent the problem alltogether by placing the subselect in an INNER JOIN of its own.
SELECT t.iteration
, t.column
FROM table t
INNER JOIN (
SELECT id, MAX(iteration) AS iteration
FROM table
WHERE id = 223652
) tm ON tm.id = t.id AND tm.iteration = t.iteration
Since you're using Oracle, I'd suggest using analytic functions for this:
SELECT * FROM (
SELECT col,
iteration,
row_number() over (partition by id order by iteration desc) rn
FROM tab
WHERE id = 223652
) WHERE rn = 1
do it like this:
with maxiteration as
(
SELECT MAX(iteration) AS maxiteration
FROM table
WHERE id = 223652
)
select
column,
iteration
from
table
where
id = 223652
AND iteration = maxiteration
;
Not 100% sure on Oracle syntax, but isn't it something like:
select iteration, column from table where id = 223652 order by iteration desc limit 1
I would approach this problem in a slightly different way. You're basically looking for the row that has no other iterations greater than it. There are at least 3 ways I can think of to do this:
SELECT
T1.iteration AS maxiteration,
T1.column
FROM
Table T1
WHERE
T1.id = 223652 AND
NOT EXISTS
(
SELECT *
FROM Table T2
WHERE
T2.id = 223652 AND
T2.iteration > T1.iteration
)
Or...
SELECT
T1.iteration AS maxiteration,
T1.column
FROM
Table T1
LEFT OUTER JOIN Table T2 ON
T2.id = T1.id AND
T2.iteration > T1.iteration
WHERE
T1.id = 223652 AND
T2.id IS NULL
Or...
SELECT
T1.iteration AS maxiteration,
T1.column
FROM
Table T1
INNER JOIN (SELECT id, MAX(iteration) AS maxiteration FROM Table T2 GROUP BY id) SQ ON
SQ.id = T1.id AND
SQ.maxiteration = T1.iteration
WHERE
T1.id = 223652
EDIT: I didn't see the ORA error the first time reading the question and it wasn't tagged as Oracle specific. I think that there may be some differences in the syntax and use of aliases in Oracle, so you may need to tweak some of the above queries.
The Oracle error is telling you that it doesn't know what maxiteration is, because the column alias isn't available yet inside the subquery. You need to refer to it by the table alias and column name instead of the column alias I believe.
You do something like
select maxiteration,column from table a join (select max(iteration) as maxiteration from table where id=1) b using (id) where b.maxiteration=a.iteration;
This could of course return multiple rows for one maxiteration unless your table has a constraint against it.