Can any body please tell me about below case.
I have fact table which has datekey, I have bridge table which has Datekey and PYdatekey( PYDatekey represents last year value).
When I want current year value, I am joining with FactTable.DateKey = BridgeTable.DateKey, for Last year values FactTable.DateKey=BridgeTable.PYDateKey.
I am writing two separate queries doing union all to get these values as rows.
But now I need to get these values as columns. Please suggest how to achieve this.
You can join to FactTable twice to get the previous and current data separately.
Use LEFT JOIN in case Datekey and/or PYdatekey is not required in BridgeTable.
--Sample data
CREATE TABLE BridgeTable (Datekey int, PYdatekey int)
CREATE TABLE FactTable (datekey int, SomeField varchar(100))
INSERT INTO FactTable VALUES (1, 'A')
INSERT INTO FactTable VALUES (2, 'B')
INSERT INTO BridgeTable VALUES (1, 2)
INSERT INTO BridgeTable VALUES (1, null)
INSERT INTO BridgeTable VALUES (null, 2)
--Query
SELECT PreviousFacts.SomeField AS Previous_SomeField, CurrentFacts.SomeField AS Current_SomeField --Or whatever columns you need
FROM BridgeTable
LEFT JOIN FactTable PreviousFacts ON BridgeTable.PYdatekey = PreviousFacts.DateKey
LEFT JOIN FactTable CurrentFacts ON BridgeTable.Datekey = CurrentFacts.DateKey
Related
I want to display a few specific Rows always at top of the query results.
For example: Cities Table. Columns: City ID, City Name
I want to fetch Query result where Mumbai, Bangalore, Chennai, Hyderabad should display at the top always.
1st way:
I can insert these records first in the table so that they will get displayed always at the top.
But, this way will not work if any other city gets added after a few months that I also want to display at the top.
Use an iif in your order by clause:
SELECT CityId, CityName
FROM Cities
ORDER BY IIF(CityName IN ('Mumbai', 'Bangalore', 'Chennai', 'Hyderabad'), 0, 1), CityName
You can't rely on the order in which you've entered the records to the table, because database tables are unsorted by nature, and without an order by clause, the order of the result set will be arbitrary.
For more information, read The “Natural order” misconception on my blog.
Try this:
Declare #t table (cityID int,cityname nvarchar(50))
insert into #t values (2,'Gujrat')
insert into #t values (4,'Surat')
insert into #t values (6,'Mumbai')
insert into #t values (3,'Bangalore')
insert into #t values (5,'Chennai')
insert into #t values (1,'Hyderabad')
select * from #t
order by case when cityname in ('Mumbai','Bangalore','Chennai','Hyderabad') then 0 else 1 END
Clean way of doing this,
Declare #t table (cityID int,cityname nvarchar(50))
Declare #DesireOrder table (id int identity,CityID int) -- instead of cityname
insert into #DesireOrder values (6),(3),(5),(1)
insert into #t values (2,'Gujrat')
insert into #t values (4,'Surat')
insert into #t values (6,'Mumbai')
insert into #t values (3,'Bangalore')
insert into #t values (5,'Chennai')
insert into #t values (1,'Hyderabad')
insert into #t values (8,'Delhi')
insert into #t values (7,'New Delhi')
select t.* from #t t
left join DesireOrder O on t.cityid=O.cityid
order by o.id,t.cityID
Main idea is #DesireOrder, rest you can implement as per your requirement.
Below are my tables and I want to calculation as per formula and insert in table3 with employees.
I have 3 tables
table1 payhead master
table2 employee payheadwise salary
table3 (the destination table)
I want to calculate as per formula column and insert into table3
For example in table 2 employeid-E001 in Pay1-2000 so for Pay2 which is formula column should calculate as per pay1 value and insert into table 3 like empid-E001,payid-pay1,amount-2000 next,Empid-E001,Payid-pay2,amount-240(calculate as 2000*12/100) NextRow-Empid-E001,Payid-pay3,Amount-2240(pay1+pay2) .so as per formula it should be calculate and insert into 3rd table.
please, somebody, help me.
CREATE TABLE #Table1
(
ID VARCHAR(5),
formula VARCHAR(MAX)
)
CREATE TABLE #table2
(
employeid VARCHAR(5),
payhead VARCHAR(5),
amount MONEY
)
CREATE TABLE #table3
(
employeid VARCHAR(5),
payiD VARCHAR(5),
amount MONEY
)
INSERT INTO #Table1
VALUES ('PAY1', NULL), ('PAY2', '(PAY1+PAY2*12%)'), ('PAY3', 'PAY1 + PAY2')
INSERT INTO #Table2
VALUES ('E001', 'PAY1', 2000), ('E002', 'PAY1', 5000), ('E003', 'PAY1', 3000)
INSERT INTO #Table2
VALUES ('E001', 'PAY3', 1000), ('E002', 'PAY3', 3000), ('E003', 'PAY3', 2000)
I have a query that joins a master and a detail table. Master table records are duplicated in results as expected. I get aggregation on detail table an it works fine. But I also need another aggregation on master table at the same time. But as master table is duplicated, aggregation results are duplicated too.
I want to demonstrate this situation as below;
If Object_Id('tempdb..#data') Is Not Null Drop Table #data
Create Table #data (Id int, GroupId int, Value int)
If Object_Id('tempdb..#groups') Is Not Null Drop Table #groups
Create Table #groups (Id int, Value int)
/* insert groups */
Insert #groups (Id, Value)
Values (1,100), (2,200), (3, 200)
/* insert data */
Insert #data (Id, GroupId, Value)
Values (1,1,10),
(2,1,20),
(3,2,50),
(4,2,60),
(5,2,70),
(6,3,90)
My select query is
Select Sum(data.Value) As Data_Value,
Sum(groups.Value) As Group_Value
From #data data
Inner Join #groups groups On groups.Id = data.GroupId
The result is;
Data_Value Group_Value
300 1000
Expected result is;
Data_Value Group_Value
300 500
Please note that, derived table or sub-query is not an option. Also Sum(Distinct groups.Value) is not suitable for my case.
If I am not wrong, you just want to sum value column of both table and show it in a single row. in that case you don't need to join those just select the sum as a column like :
SELECT (SELECT SUM(VALUE) AS Data_Value FROM #DATA),
(SELECT SUM(VALUE) AS Group_Value FROM #groups)
SELECT
(
Select Sum(d.Value) From #data d
WHERE EXISTS (SELECT 1 FROM #groups WHERE Id = d.GroupId )
) AS Data_Value
,(
SELECT Sum( g.Value) FROM #groups g
WHERE EXISTS (SELECT 1 FROM #data WHERE GroupId = g.Id)
) AS Group_Value
I'm not sure what you are looking for. But it seems like you want the value from one group and the collected value that represents a group in the data table.
In that case I would suggest something like this.
select Sum(t.Data_Value) as Data_Value, Sum(t.Group_Value) as Group_Value
from
(select Sum(data.Value) As Data_Value, groups.Value As Group_Value
from data
inner join groups on groups.Id = data.GroupId
group by groups.Id, groups.Value)
as t
The edit should do the trick for you.
I have two tables with foreign key constraint on TableB on TablesAs KeyA column. I was doing manual inserts till now as they were only few rows to be added. Now i need to do a bulk insert, so my question if i insert multiple rows in TableA how can i get all those identity values and insert them into TableB along with other column values. Please see the script below.
INSERT INTO Tablea
([KeyA]
,[Value] )
SELECT 4 ,'StateA'
UNION ALL
SELECT 5 ,'StateB'
UNION ALL
SELECT 6 ,'StateC'
INSERT INTO Tableb
([KeyB]
,[fKeyA] //Get value from the inserted row from TableA
,[Desc])
SELECT 1 ,4,'Value1'
UNION ALL
SELECT 2 ,5,'Value2'
UNION ALL
SELECT 3 ,6, 'Value3'
You can use the OUTPUT clause of INSERT to do this. Here is an example:
CREATE TABLE #temp (id [int] IDENTITY (1, 1) PRIMARY KEY CLUSTERED, Val int)
CREATE TABLE #new (id [int], val int)
INSERT INTO #temp (val) OUTPUT inserted.id, inserted.val INTO #new VALUES (5), (6), (7)
SELECT id, val FROM #new
DROP TABLE #new
DROP TABLE #temp
The result set returned includes the inserted IDENTITY values.
Scope identity sometimes returns incorrect value. See the use of OUTPUT in the workarounds section.
I have two tables as shown in the example. Now I want to select the data in the format presented in the comment lines below.
create table cust (nbr varchar(8))
create table data (nbr varchar(8),fld varchar(8),val varchar(8))
insert into cust (nbr) values ('AA')
insert into data (nbr,fld,val) values ('AA','1','one')
insert into data (nbr,fld,val) values ('AA','2','two')
insert into data (nbr,fld,val) values ('AA','3','three')
insert into data (nbr,fld,val) values ('AA','1','uno')
insert into data (nbr,fld,val) values ('AA','2','dos')
insert into data (nbr,fld,val) values ('AA','3','tres')
select * from cust
select * from data
drop table cust
drop table data
-- AA, One, Two, Three
-- AA, Uno, Dos, Tres
Any ideas how to join these tables to get the desired output.
At the moment you don't have anything in the data table which would allow you to group the rows into anything you can work with. If you add a languageID column to the data table as suggested by #avery_larry, you could write your select as follows:
create table cust (nbr varchar(8))
create table data (nbr varchar(8),fld varchar(8),val varchar(8), languageID int)
insert into cust (nbr) values ('AA')
insert into data (nbr,fld,val, languageID) values ('AA','1','one', 1)
insert into data (nbr,fld,val, languageID) values ('AA','2','two', 1)
insert into data (nbr,fld,val, languageID) values ('AA','3','three', 1)
insert into data (nbr,fld,val, languageID) values ('AA','1','uno', 2)
insert into data (nbr,fld,val, languageID) values ('AA','2','dos', 2)
insert into data (nbr,fld,val, languageID) values ('AA','3','tres', 2);
select * from cust;
select * from data;
with data_cte(nbr, languageID)
as
(
select nbr, languageID
from data with (nolock)
group by nbr, languageID
)
select c.nbr,
SUBSTRING(
(
SELECT ','+d.val AS [text()]
FROM [data] d
WHERE d.nbr = dc.nbr and d.languageID = dc.languageID
ORDER BY d.fld
FOR XML PATH ('')
), 2, 1000) as 'Values'
from data_cte dc
inner join cust c on c.nbr = dc.nbr;
drop table cust
drop table data
The sql for concatenating the strings was taken from this post How to concatenate text from multiple rows into a single text string in SQL server?, with a slight tweek to add the with.
Hope this helps.