i have two temp tabels like this:
t1 t2
id a b c id a b c
1 250
2 251
3 .
. .
.
250
251
.
.
id 250 from t2 is equal with id 1 from t1
id 251 from t2 is equal
with id 2 from t1 and so on.
how can i achieve something like this?
select id, a, b, c
from #t1
join #t2
on #t1.id - 249 = #t2.id
I need this because i need to perform calculations, example:
(the value from a with the id 250 from t1 - the value from a with id 1
from t1 ) * 100 in a new column
Thanks
You've got it right except for resolving ambiguity in your query. See below syntax
select
t1.*,
t2.*,
(t2.a-t1.a)*100 as result
from #t1 t1
join #t2 t2
on t1.id - 249 = t2.id
further based on your comment to question
I have 1 table and i perform two different queries to create 2 temp
tables. From there you know the story. I want to insert the result
into another temp table.
I'd suggest that instead of creating temp tables used the select queries as inner queries in join like below so that problems with temp tables being invisible at a part is not a hinderance. This saves on memory as well.
select
t1.*,
t2.*,
(t2.a-t1.a)*100 as result
from
(
select id,a,b,c from orig_table
-- where ....
) t1
join
(
select id,a,b,c from orig_table
-- where ....
) t2
on t1.id - 249 = t2.id
update
Do you have any idea how i could write this for 12 different cases?
insetead copy pasting the query 12 times. example: case when a like
'e1m' or 'e2m', or 'ey1' and so on, 12 in total
Based on asker's comment I'd suggest that following query is a better approach:
select
id as orig_id,
a,
b,
case when c like 'c1' then c else Null end as t1c,
case when c like 'c1' then id-249 else Null end as t1id,
case when c like 'c2' then c else Null end as t2c,
case when c like 'c1' then id-249*2 else Null end as t2id
from orig_table
Put this as inner query and we can quickly do all calculations over this inner query result set instead of all those joins
demo Sql fiddle link here:http://sqlfiddle.com/#!6/b7aee/4
This will work:
select * from #t1 JOIN #t2 ON (#t2.id -249)= #t1.id
If you have Problem with expireed sessions, please try to use global temps with ##
if that is not working try to manualy create table in the Folder
YourDB\Databse\System Databases\Tempdb
Table variables (DECLARE #t TABLE) are visible only to the connection that creates it, and are deleted when the batch or stored procedure ends.
Local temporary tables (CREATE TABLE #t) are visible only to the
connection that creates it, and are deleted when the connection is
closed.
Global temporary tables (CREATE TABLE ##t) are visible to everyone,
and are deleted when all connections that have referenced them have closed.
Tempdb permanent tables (USE tempdb CREATE TABLE t) are visible to
everyone, and are deleted when the server is restarted.
Related
I have table 1 with data and table 2 as a lookup table with metadata. I need a query that returns all records from table 1 where either column in table 1 not exists in table two.
The following query works fine for one column, but if I use more than one column in my join it´s not.
working query:
select
T1.SCENARIO,
T1.year,
T1.period,
T1.ENTITY,
T1.account,
T1.ICP,
T1.MVMTS,
T1.C1,
T1.C2,
T1.C3,
T1.MULTI_GAAP,
T1.VLAUE
from
"fccs".MV_FACT_FCCS T1
left outer join "fccs".V_META_NOT_FOUND V2 on trim(T1.account) = trim(V2.account)
where
V2.account is null
not working correctly:
select
T1.SCENARIO,
T1.year,
T1.period,
T1.ENTITY,
T1.account,
T1.ICP,
T1.MVMTS,
T1.C1,
T1.C2,
T1.C3,
T1.MULTI_GAAP,
T1.VLAUE
from
"fccs".MV_FACT_FCCS T1
left outer join "fccs".V_META_NOT_FOUND V2 on trim(T1.account) = trim(V2.account)
and trim(T1.entity) = trim(v2.entity)
where
V2.account is null or v2.entity is null
The second query continues to bring the records from table 1 where exist in table 2.
Any help appreciated!
I need a query that returns all records from table 1 where either column in table 1 not exists in table two.
Use not exists:
select ff.*
from "fccs".MV_FACT_FCCS ff
where not exists (select 1
from "fccs".V_META_NOT_FOUND mnf
where trim(ff.account) = trim(mnf.account)
) or
not exists (select 1
from "fccs".V_META_NOT_FOUND mnf
where trim(ff.entity) = mnf.trimc
) ;
Note: This answers the question as written. You might mean that both conditions are not met. In that case, use and instead of or.
I have two user defined table type in SQL server 2012 table #Table1 with column name as ColumnTable1 and #Table2 with one of the columns as ColumnTable2.
I wish to select data from a physical table named employeeData. This table has both the columns(ColumnTable1 and ColumnTable2 in it).
What I want is when both #table1 and #table2 have data, then values matching from the both the UDT in employeeData should be returned. If only one of them, then values matching from that table should be returned and if both are null, then all the data from Employeedata table must be returned.
I tried a query which works fine of both of them are not null.
SELECT * FROM employeeData WHERE
(((NOT EXISTS (SELECT 1 FROM #Table1) OR ColumnTable1 IN (SELECT
ColumnTable1 FROM #Table1)) AND (NOT EXISTS (SELECT 1 FROM #Table2)
OR ColumnTable2 in (SELECT ColumnTable2 FROM #Table2)))
PS: this example is for only two tables, I may need to add new such user defined tables in future for similar filtering.
try this
select t.*
from employeeData t
left join #Table1 t1 on t1.ColumnTable1 =t.ColumnTable1
left join #Table2 t2 on t2.ColumnTable2 =t.ColumnTable2
where
not (t1.ColumnTable1 is null and exists (select top 1 1 from #Table1))
and
not (t2.ColumnTable2 is null and exists (select top 1 1 from #Table2))
I am trying to alter a base query that selects data from several joined tables, and filters out rows based on the CASE WHEN below. The result set is to be returned as follows:
If all of the rows return 0 in the CASE column, return one line with '0' in the OVERDUE column (the "return one line" portion is taken care of by DISTINCT.)
If any of the rows return 1 for the CASE column, return one line with '1' in the OVERDUE column.
The base is as follows:
SELECT DISTINCT t1.*,
CASE WHEN t3.MTemp > t3.MTempLimit
then 1
when t3.TotHours > t3.THoursLimit
then 1
else 0
end [Overdue]
from table_1 t1
LEFT JOIN table_2 t2 on t1.ResNo = t2.ResNo and t1.PCode = t2.PCode
LEFT JOIN table_3 t3 on t2.RepJobNo = t3.RepJobNo
LEFT JOIN table_4 t4 on t4.TypeID = t2.RepType
WHERE t2.RepStat = 1
The catch is, I've already created a working version of this by using a temp table and doing a IF EXISTS/ELSE query on the temp table's OVERDUE column. However, I've been informed that this solution may not be useable (due to having to go through certain front-end software).
Is it possible to do a workaround for this that does not involve using a temporary table? I've been making attempts at using both a derived table and CTEs, neither of which have yielded anything usable, due to the fact that one cannot use IF/ELSE clauses after those (which was what I was counting on).
I'm still getting the hang of T-SQL, so any help would be greatly appreciated.
Sounds like a simple ROW_NUMBER() and a couple of CTEs will work:
;WITH RS1 as (
SELECT t1.*,
CASE WHEN t3.MTemp > t3.MTempLimit
then 1
when t3.TotHours > t3.THoursLimit
then 1
else 0
end [Overdue]
from table_1 t1
LEFT JOIN table_2 t2 on t1.ResNo = t2.ResNo and t1.PCode = t2.PCode
LEFT JOIN table_3 t3 on t2.RepJobNo = t3.RepJobNo
LEFT JOIN table_4 t4 on t4.TypeID = t2.RepType
WHERE t2.RepStat = 1
), RS2 as (
select *,ROW_NUMBER() OVER (ORDER BY Overdue DESC) rn
from RS1
)
select * from RS2 where rn = 1
(There's no need for a DISTINCT now that we're only returning one row)
In general any temporary table referenced in another query can simply be substituted for as follow, so that this:
insert #temp
select -- definition of temptable
;
select ...
from #temp
join ...
becomes
select
from (
-- definition of temptable
) temp
join ...
How does SQLite internally treats the alias?
Does creating a table name alias internally creates a copy of the same table or does it just refers to the same table without creating a copy?
When I create multiple aliases of the same table in my code, performance of the query is severely hit!
In my case, I have one table, call it MainTable with namely 2 columns, name and value.
I want to select multiple values in one row as different columns. for example
Name: a,b,c,d,e,f
Value: p,q,r,s,t,u
such that a corresponds to p and so on.
I want to select values for names a,b,c and d in one row => p,q,r,s
So I write a query
SELECT t1.name, t2.name, t3.name, t4.name
FROM MainTable t1, MainTable t2, MainTable t3, MainTable t4
WHERE t1.name = 'a' and t2.name = 'b' and t3.name = 'c' and t4.name = 'd';
This way f writing the query kills the performance when size of the table increases as rightly pointed above by Larry.
Is there any efficient way to retrieve this result. I am bad at SQL queries :(
If you list the same table more than once in your SQL statement and do not supply conditions on which to JOIN the tables, you are creating a cartesian JOIN in your result set and it will be enormous:
SELECT * FROM MyTable A, MyTable B;
if MyTable has 1000 records, will create a result set with one million records. Any other selection criteria you include will then have to be evaluated across all one million records.
I'm not sure that's what you're doing (your question is very unclear), but it may be a start on solving your problem.
Updated answer now that the poster has added the query that is being executed.
You're going to have to get a little tricky to get the results you want. You need to use CASE and MAX and, unfortunately, the syntax for CASE is a little verbose:
SELECT MAX(CASE WHEN name='a' THEN value ELSE NULL END),
MAX(CASE WHEN name='b' THEN value ELSE NULL END),
MAX(CASE WHEN name='c' THEN value ELSE NULL END),
MAX(CASE WHEN name='d' THEN value ELSE NULL END)
FROM MainTable WHERE name IN ('a','b','c','d');
Please give that a try against your actual database and see what you get (of course, you want to make sure the column name is indexed).
Assuming you have table dbo.Customers with a million rows
SELECT * from dbo.Customers A
does not result in a copy of the table being created.
As Larry pointed out, the query as it stands is doing a cartesian product across your table four times which, as you has observed, kills your performance.
The updated ticket states the desire is to have 4 values from different queries in a single row. That's fairly simple, assuming this syntax is valid for sqllite
You can see that the following four queries when run in serial produce the desired value but in 4 rows.
SELECT t1.name
FROM MainTable t1
WHERE t1.name='a';
SELECT t2.name
FROM MainTable t2
WHERE t2.name='b';
SELECT t3.name
FROM MainTable t3
WHERE t3.name='c';
SELECT t4.name
FROM MainTable t4
WHERE t4.name='d';
The trick is to simply run them as sub queries like so there are 5 queries: 1 driver query, 4 sub's doing all the work. This pattern will only work if there is one row returned.
SELECT
(
SELECT t1.name
FROM MainTable t1
WHERE t1.name='a'
) AS t1_name
,
(
SELECT t2.name
FROM MainTable t2
WHERE t2.name='b'
) AS t2_name
,
(
SELECT t3.name
FROM MainTable t3
WHERE t3.name='c'
) AS t3_name
,
(
SELECT t4.name
FROM MainTable t4
WHERE t4.name='d'
) AS t4_name
Aliasing a table will result a reference to the original table that exists for the duration of the SQL statement.
Table1
...
LogEntryID *PrimaryKey*
Value
ThresholdID - - - Link to the appropriate threshold being applied to this log entry.
...
Table2
...
ThresholdID *PrimaryKey*
Threshold
...
All fields are integers.
The "..." thingies are there to show that these tables hold a lot more imformation than just this. They are set up this way for a reason, and I can't change it at this point.
I need write a SQL statement to select every record from Table1 where the Value field in that particular log record is less than the Threshold field in the linked record of Table2.
I'm newish to SQL, so I know this is a basic question.
If anyone can show me how this SQL statement would be structured, it would be greatly appreciated.
SELECT T1.*
FROM Table1 T1
JOIN Table2 T2 ON T2.ThresholdID = T1.ThresholdID
WHERE T2.Threshold > T1.Value
SELECT t1.*
FROM dbo.Table1 t1 INNER JOIN dbo.Table2 t2 ON t1.ThresholdID = t2.ThresholdID
WHERE t2.Threshold > t1.Value
SELECT * from table1 t1 join table2 t2 on (t1.thresholdId = t2.thresholdId)
where t1.value < t2.threshold;
SELECT t1.LogEntryID, t1.Value, t1.ThresholdID
FROM Table1 t1
INNER JOIN Table2 t2 ON t1.ThresholdID = t2.ThresholdID
WHERE t1.Value < t2.threshold
SELECT * FROM Table1
JOIN Table2
ON table1.ThresholdID = table2.ThresholdID --(assuming table 2 holds the same value to link them together)
WHERE
value < thresholdvalue
A 'JOIN' connects 2 tables based on the 'ON' clause (which can be multipart, using 'AND' and 'OR')
If you have 3 entries in table 2 which share table1's primary key (a one-to-many association) you will receive 3 rows in your result set.
for the tables below, for example:
Table 1:
Key Value
1 Hi
2 Bye
Table 2:
Table1Key 2nd_word
1 You
1 fellow
1 friend
2 now
this query:
SELECT * FROM Table1
JOIN Table2
on table1.key = table2.table1key
gets this result set:
Key Value Table1Key 2nd_word
1 Hi 1 You
1 Hi 1 fellow
1 Hi 1 friend
2 Bye 2 now
Note that JOIN will only return results when there is a match in the 2nd table, it will not return a result if there is no match. You can LEFT JOIN for that (all fields from the second table will be NULL).
JOINs can also be strung together, the result from the previous JOIN is used in place of the original table.