How to get SQL SERVER 2008 r2 data in a column - sql-server-2008

I have two different tables :
Tank & FillingStations
In which one tank can be attached to many fillingstations.
Suppose:
SrNo TankID TankName TANK_Balance FillingStation_ID FS_NAme BALANCE
1 1 Tank1 5000 A11 FSA11 1545
2 1 Tank1 5000 A12 FSA12 1000
3 1 Tank1 5000 A13 FSA13 800
And i want to get a report as like :
SrNo TankID TankName TANK_Balance A11 BAL1 A12 BAL2 A13 BAL3 TOTAL
1 1 Tank1 5000 FSA11 1545 FSA12 1000 FSA13 800 3345

Try like this,
DECLARE #Table TABLE (
SrNo INT
,TankID INT
,TankName VARCHAR(10)
,TANK_Balance INT
,FillingStation_ID VARCHAR(10)
,FS_NAme VARCHAR(10)
,BALANCE INT
)
insert into #Table values
(1,1,'Tank1',5000,'A11','FSA11',1545)
,(2,1,'Tank1',5000,'A12','FSA12',1000)
,(3,1,'Tank1',5000,'A13','FSA13',800)
SELECT min(SrNo) as SrNo, TankID
,TankName
,TANK_Balance
,max([A11]) AS [A11]
,max([BAL1]) AS [BAL1]
,max([A12]) AS [A12]
,max([BAL2]) AS [BAL2]
,max([A13]) AS [A13]
,max([BAL3]) AS [BAL3]
,max([BAL1])+max([BAL2])+max([BAL3]) as Total
FROM (
SELECT SrNo,TankID
,TankName
,TANK_Balance
,FillingStation_ID
,replace(FillingStation_ID, 'A1', 'BAL') AS bFillingStation_ID
,FS_NAme
,BALANCE
FROM #Table
) s
pivot(Max(FS_NAme) FOR FillingStation_Id IN (
[A11]
,[A12]
,[A13]
)) t
pivot(Max(BALANCE) FOR bFillingStation_Id IN (
[BAL1]
,[BAL2]
,[BAL3]
)) t1
GROUP BY TankID
,TankName
,TANK_Balance

Related

How to do a loop to fill a database table in MySQL?

I just wanted to know how to do a loop and fill a database table with fake data in order to get 500,000 records. I have a table with the following fields, for customer_id we have 1-1000, staff_id we have 1-5 staff, car_id is between 1-10,000, qty is 1-3, date_ordered is from 1975 to 2017, date_returned is from 1975 to 2017, For the dates the difference between date_ordered and date_returned should be between 2-3 days.
Any help on this would be much appreciated!
CREATE TABLE car_transaction
(
transaction_id INTEGER NOT NULL,
customer_id INTEGER,
staff_id INTEGER,
car_ID INTEGER,
QTY INTEGER,
date_ordered,
date_returned,
PRIMARY KEY (transaction_id));
This is totally possible with only pure MySQL SQL code.
This is the table i've used
CREATE TABLE car_transaction
(
transaction_id INTEGER NOT NULL AUTO_INCREMENT, # included AUTO_INCREMENT HERE
customer_id INTEGER,
staff_id INTEGER,
car_ID INTEGER,
QTY INTEGER,
date_ordered DATE, # made DATE type
date_returned DATE, # made DATE type
PRIMARY KEY (transaction_id)
);
for customer_id we have 1-1000, staff_id we have 1-5 staff, car_id is
between 1-10,000, qty is 1-3
These fields have clear requirements about there range use can use MySQL rand() function in combination with a formula to generate those ranges this formula is
SELECT ROUND((RAND() * (MAX - MIN)) + MIN)
So for example for customer id the formula is
SELECT ROUND((RAND() * (1000 - 1)) + 1)
first try result
ROUND((RAND() * (1000 - 1)) + 1)
----------------------------------
648
second try result
ROUND((RAND() * (1000 - 1)) + 1)
----------------------------------
486
date_ordered is from 1975 to 2017, date_returned is from 1975 to 2017,
For the dates the difference between date_ordered and date_returned
should be between 2-3 days.
The date formula is a bit more complex.
But it still uses the ROUND((RAND() * (MAX - MIN)) + MIN) formula
SELECT DATE(FROM_UNIXTIME(ROUND((RAND() * (UNIX_TIMESTAMP('2017-12-31') - UNIX_TIMESTAMP('1975-01-01'))) + UNIX_TIMESTAMP('1975-01-01'))))
first try result
DATE(FROM_UNIXTIME(ROUND((RAND() * (UNIX_TIMESTAMP('2017-12-31') - UNIX_TIMESTAMP('1975-01-01'))) + UNIX_TIMESTAMP('1975-01-01'))))
-------------------------------------------------------------------------------------------------------------------------------------
2005-08-04
second try result
DATE(FROM_UNIXTIME(ROUND((RAND() * (UNIX_TIMESTAMP('2017-12-31') - UNIX_TIMESTAMP('1975-01-01'))) + UNIX_TIMESTAMP('1975-01-01'))))
-------------------------------------------------------------------------------------------------------------------------------------
1998-07-22
Now we will generate one record off data to combine all the last steps.
Query
SELECT
record.customer_id
, record.staff_id
, record.car_id
, record.qty
, record.date_ordered
, record.date_ordered + INTERVAL record.random_day DAY AS date_returned
FROM (
SELECT
(SELECT ROUND((RAND() * (1000 - 1)) + 1)) AS customer_id
, (SELECT ROUND((RAND() * (5 - 1)) + 1)) AS staff_id
, (SELECT ROUND((RAND() * (10000 - 1)) + 1)) AS car_id
, (SELECT ROUND((RAND() * (3 - 1)) + 1)) AS qty
, (DATE(FROM_UNIXTIME(FLOOR((RAND() * (UNIX_TIMESTAMP('2017-12-31') - UNIX_TIMESTAMP('1975-01-01'))) + UNIX_TIMESTAMP('1975-01-01')))) ) AS date_ordered
, (SELECT ROUND((RAND() * (3 - 2)) + 2)) AS random_day
FROM
DUAL
)
record
first try result
customer_id staff_id car_id qty date_ordered date_returned
----------- -------- ------ ------ ------------ ---------------
633 2 5553 3 2011-11-21 2011-11-24
second try result
customer_id staff_id car_id qty date_ordered date_returned
----------- -------- ------ ------ ------------ ---------------
300 4 2380 2 2010-08-21 2010-08-23
Procedure
DELIMITER $$
CREATE
PROCEDURE generate_random_data_car_transaction(IN numberOfRows INT)
BEGIN
DECLARE counter INT;
SET counter = 1;
WHILE (counter <= numberOfRows) DO
INSERT INTO
car_transaction
(
customer_id
, staff_id
, car_id
, qty
, date_ordered
, date_returned
)
SELECT
record.customer_id
, record.staff_id
, record.car_id
, record.qty
, record.date_ordered
, record.date_ordered + INTERVAL record.random_day DAY AS date_returned
FROM (
SELECT
(SELECT ROUND((RAND() * (1000 - 1)) + 1)) AS customer_id
, (SELECT ROUND((RAND() * (5 - 1)) + 1)) AS staff_id
, (SELECT ROUND((RAND() * (10000 - 1)) + 1)) AS car_id
, (SELECT ROUND((RAND() * (3 - 1)) + 1)) AS qty
, (DATE(FROM_UNIXTIME(FLOOR((RAND() * (UNIX_TIMESTAMP('2017-12-31') - UNIX_TIMESTAMP('1975-01-01'))) + UNIX_TIMESTAMP('1975-01-01')))) ) AS date_ordered
, (SELECT ROUND((RAND() * (3 - 2)) + 2)) AS random_day
FROM
DUAL
)
record;
SET counter = counter + 1;
END WHILE;
END$$
DELIMITER ;
CALL Procedure
CALL generate_random_data_car_transaction(500000);
Query
SELECT * FROM car_transaction
Result
transaction_id customer_id staff_id car_ID QTY date_ordered date_returned
-------------- ----------- -------- ------ ------ ------------ ---------------
1 757 2 2621 2 1982-03-10 1982-03-13
2 818 1 368 3 1989-06-06 1989-06-08
3 47 2 8538 2 2009-09-30 2009-10-02
4 670 2 4597 2 2005-03-20 2005-03-22
5 216 2 7651 3 2000-10-08 2000-10-10
6 502 2 1364 2 1978-03-28 1978-03-30
7 204 2 1910 2 2009-03-17 2009-03-20
8 398 2 3934 1 2013-07-02 2013-07-04
9 474 1 9286 2 1991-08-06 1991-08-09
10 976 1 724 2 2000-05-09 2000-05-12
...
...
...
499990 20 5 6595 2 1990-05-01 1990-05-03
499991 839 1 7315 2 1989-12-05 1989-12-07
499992 14 3 1274 2 1987-11-12 1987-11-14
499993 539 2 5422 1 1994-06-24 1994-06-26
499994 728 5 7441 3 2000-05-12 2000-05-15
499995 512 3 4039 2 1978-02-03 1978-02-06
499996 732 5 2599 2 1990-01-11 1990-01-14
499997 304 5 6098 2 2011-11-25 2011-11-27
499998 818 2 8196 2 1984-01-14 1984-01-16
499999 617 5 8160 2 2016-03-15 2016-03-18
500000 864 3 7837 2 1980-01-13 1980-01-15
If this were my project I'd look around the intertoobz for a software package or web app capable of generating random test data.
I'd get that to give me a CSV file full of data for all columns except the first.
I'd change the table definition to make the first column autoincrement.
Then I'd use
LOAD DATA INFILE filename INTO car_transaction
COLUMNS TERMINATED BY ','
LINES TERMINATED BY '\r\n' /* or maybe just '\n' */
(customer_id, staff_id, car_ID, QTY, date_ordered, date_returned)
to slurp the data from the file (called filename) into the table.

Stored Procedure in data mining prediction

I am trying to write a stored procedure to display (fid, name,tel,income,balance,loan_amount, child_count) from two tables
Family(fid,name,tel,income,good_credit,balance)
Children(cid,name,age,fid). The function should be able to predict who can be a potential customer based on the following criteria:
Good credit, balance>=3000, child_count:total number of children between age 18 and 22, income:40000 and loan_amount = income * 0.3 * child_count
Family table
fid name tel income good_credit balance
1 aaa1 111 15000 1 1000
2 aaa2 211 25000 0 10000
3 aaa3 311 80000 0 1000
4 aaa4 411 40000 1 7000
Children table
cid name age fid
1 bbb1 14 3
2 bbb2 14 15
3 bbb3 19 16
4 bbb4 18 9
My code looks like this, but i got an error "subquery returns more than one row"
delimiter $$
CREATE PROCEDURE procc()
BEGIN
declare loan_amount int (200);
declare child_count int (200);
set child_count = (select count(age) from Children,Family where age between 18 and 22 );
set loan_amount = (select income from Children CV,Family DV where DV.FID = CV.FID);
if (child_count is not null) then select cf.FID as FID, cf.Name as Name, cf.TEL as TEL, cf.income as income, cf.balance as balance, child_count, loan_amount * 0.3 * child_count from Family cf,Children cc
where cf.FID = cc.FID and good_credit = 1 and income >= 40000 and balance = 3000;
end if;
end$$
delimiter ;

How to query 2 SQL tables & change data with 1 query

i'm having difficulties on query 2 tables & change the data on those 2 tables.
Here's what i wanted to do.
Get Table B "Max Qty" - Table A ("Actual Qty" - "WIP Qty") = Table B "Topup Qty"
Then change "Signal" value into NULL or 1-4 legend base on (("Actual Qty" - "WIP Qty") / "Max Qty") x 100%
Legend
NULL = More than or equal to 60%
1 = Less than or equal to 60%
2 = Less than or equal to 50%
3 = Less than or equal to 30%
4 = Less than or equal to 0%
From this:
TABLE A
- Products Actual Qty WIP QTY
- Product A 5 0
- Product B 5 0
- Product C 733 72
- Product D 532 90
- Product E 510 360
TABLE B
- MIN QTY MAX QTY TOPUP QTY SIGNAL
- 100 1000 NULL NULL
- 329 857 NULL NULL
- 393 1025 NULL NULL
- 262 683 NULL NULL
- 319 832 NULL NULL
To become like this:
TABLE A
- Products Actual Qty WIP QTY
- Product A 5 0
- Product B 5 0
- Product C 733 72
- Product D 532 90
- Product E 510 360
TABLE B
- MIN QTY MAX QTY TOPUP QTY SIGNAL
- 100 1000 995 4
- 329 857 852 4
- 393 1025 220 NULL
- 262 683 61 NULL
- 319 832 680 4
I am assuming that TableB has some relation to TableA
This will not be possible if there is no way to relate between them.
DECLARE #tableA TABLE(Products VARCHAR(50), Actual_Qty INT, WIP_Qty INT)
DECLARE #tableB TABLE(Products VARCHAR(50), Min_Qty INT, Max_Qty INT, Topup_Qty INT, Signal INT)
INSERT INTO #tableA VALUES
('Product A',5, 0),
('Product B', 5, 0),
('Product C', 733 , 72),
('Product D', 532 , 90),
('Product E', 510 , 360)
INSERT INTO #tableB VALUES
('Product A',100, 1000,995, 4),
('Product B',329, 857 ,852, 4),
('Product C',393, 1025,220, NULL),
('Product D',262, 683 ,61 , NULL),
('Product E',319, 832 ,680, 4)
SELECT A.Products,A.Actual_Qty,A.WIP_Qty,A.Actual_Qty-A.WIP_Qty Topup,'>' [ ],B.Products,B.Min_Qty,B.Max_Qty,B.Topup_Qty,B.Signal, 'now calculate > ' [ ]
, CONVERT(MONEY,(A.Actual_Qty-A.WIP_Qty )*100)/B.Max_Qty SignalTest
, CASE
WHEN CONVERT(MONEY,(A.Actual_Qty-A.WIP_Qty )*100)/B.Max_Qty >= 60 THEN 1
WHEN CONVERT(MONEY,(A.Actual_Qty-A.WIP_Qty )*100)/B.Max_Qty BETWEEN 50 AND 60 THEN 2
WHEN CONVERT(MONEY,(A.Actual_Qty-A.WIP_Qty )*100)/B.Max_Qty BETWEEN 30 AND 50 THEN 3
WHEN CONVERT(MONEY,(A.Actual_Qty-A.WIP_Qty )*100)/B.Max_Qty < 30 THEN 4
END Signal
FROM #tableA A
INNER JOIN #tableB B ON B.Products = A.Products
/*Here is the update but, you can switch the tables for your tables*/
UPDATE B
SET B.Signal = (SELECT CASE
WHEN CONVERT(MONEY,(A.Actual_Qty-A.WIP_Qty )*100)/B.Max_Qty >= 60 THEN 1
WHEN CONVERT(MONEY,(A.Actual_Qty-A.WIP_Qty )*100)/B.Max_Qty BETWEEN 50 AND 60 THEN 2
WHEN CONVERT(MONEY,(A.Actual_Qty-A.WIP_Qty )*100)/B.Max_Qty BETWEEN 30 AND 50 THEN 3
WHEN CONVERT(MONEY,(A.Actual_Qty-A.WIP_Qty )*100)/B.Max_Qty < 30 THEN 4
END Signal)
FROM #tableA A
INNER JOIN #tableB B ON B.Products = A.Products
SELECT
*
FROM #tableB

Removing duplicate values from a dataset

I am developing an SSRS report with the following dataset (Table-1). I am grouping by Account and Period. My goal is to get the Total Expense and the Budget within a group. Because the Budget data is duplicated per group, I cannot use SUM() function for Budget. How do I remove the duplicates so the new dataset looks like this? (Table-2) Please advice. Thank you for your time.
Table-1
ID Account Period Expense Budget
1 100 201301 20 100
2 100 201301 30 100
3 100 201302 10 150
4 100 201302 40 150
5 200 ...................
Table-2
ID Account Period Expense Budget
1 100 201301 20 100
2 100 201301 30 NULL
3 100 201302 10 150
4 100 201302 40 NULL
5 200 ...................
If you really want to make duplicate budgets null try this update command
please check sqlfiddle http://sqlfiddle.com/#!3/1e619/11
Update table1
set budget = null
where id in
(
select aa.id from
(
select id,row_number()
over(partition by Budget order by Period) as rno
from table1
) aa
where rno > 1
);
select * from table1;
good luck.
I would use a windowed function if you have to do that grouping in SQL. If you can do it in SSRS just add a 'Row Grouping Parent' it would be better.
For SQL I would do this:
declare #Temp table ( ID int identity, Account int, period int, expense int, budget int);
insert into #Temp values (100, 201301, 20, 100),(100, 201301, 30, 100),(100, 201302, 10, 150),(100, 201302, 40, 150)
select *
from #Temp
select
ID
, Account
, Period
, Expense
, case when (row_number() over(partition by Budget order by Period) = 1) then Budget end as Budget-- only shows first occurrence of an order amount ordering by person
from #Temp

Select All Columns By Most Recent Date and Highest Version

I have been stumped on this for quite awhile. Request#, SlotId, Segment, and Version all make up the primary key. What i want from my stored proc is to be able to retrieve all rows by passing in the Request # and Segment, but for each slot i want the most recent effective date on or before todays date and from that i need the highest version #. I appriciate your time.
Values in database
Request# SlotId Segment Version Effective Date ContentId
A123 1 A 1 2012-01-01 1
A123 2 A 1 2012-01-01 2
A123 2 A 2 2012-02-01 34
A123 2 A 3 2012-02-01 24
A123 2 A 4 2015-01-01 6 //beyond todays date. dont want
Values I want to return from my stored proc when i pass in A123 for Request # and A for Segment.
A123 1 A 1 2012-01-01 1
A123 2 A 3 2012-02-01 24
The query could be written like this:
; WITH cte AS
( SELECT Request, SlotId, Segment, Version, [Effective Date], ContentId,
ROW_NUMBER() OVER ( PARTITION BY Request, Segment, SlotId
ORDER BY Version DESC ) AS RowN
FROM
tableX
WHERE
Request = #Req AND Segment = #Seg --- the 2 parameters
AND [Effective Date] < DATEADD(day, 1, GETDATE())
)
SELECT Request, SlotId, Segment, Version, [Effective Date], ContentId
FROM cte
WHERE Rn = 1 ;
Consider this:
;
WITH A as
(
SELECT DISTINCT
Request
, Segment
, SlotId
FROM Table1
)
SELECT A.Request
, A.SlotId
, A.Segment
, B.EffectiveDate
, B.Version
, B.ContentID
FROM A
JOIN (
SELECT Top 1
Request
, SlotId
, Segment
, EffectiveDate
, Version
, ContentId
FROM Table1 t1
WHERE t1.Request = A.Request
AND t1.SlotId = A.SlotId
AND T1.Segment = A.Segment
AND T1.EffectiveDate <= GetDate()
ORDER BY
T1.EffectiveDate DESC
, T1.Version DESC
) as B
ON A.Request = B.Request
AND A.SlotId = B.SlotId
AND A.Segment = B.Segment