Solution: I had to add a WHERE clause to both SELECT queries.
I'm working on a SQL Server 2008 database.
I'm trying to write a SQL query to return a resultset like that :
date | turnover_centrale | turnover_public
+------------+----------------------+--------------------
| 2017-02-14 | 233.34 | 383.83
| 2017-03-14 | 142.81 | 166.8
| 2017-04-14 | 173.25 | 250.51
| 2017-05-14 | 186.96 | 245.08
| 2017-06-14 | 61.26 | 97.67
| 2017-07-14 | 262.98 | 356.16
| 2017-08-14 | 89.88 | 162.38
| 2017-09-14 | 250.32 | 381.47
| 2017-10-14 | 386.06 | 581.96
| Total | Result of the column | Result of the column
My SQL query is :
SELECT
CLC_DATE, CLC_PRIX_CENTRALE, CLC_PRIX_PUBLIC
FROM
##.dbo.CLIENTS_CONSO
WHERE
CF_USER = :ref
UNION ALL
SELECT
NULL, SUM(CLC_PRIX_CENTRALE), SUM(CLC_PRIX_PUBLIC)
FROM
##.dbo.CLIENTS_CONSO
The result of the last row is unfortunately false :(
So do you have a better solution ?
Thanks a lot!
Considering that each date only has one entry, perhaps:
WITH VTE AS (
SELECT CONVERT(date,[date]) AS [date], turnover_centrale, turnover_public
FROM (VALUES
('20170214',233.34,383.83),
('20170314',142.81,166.8 ),
('20170414',173.25,250.51),
('20170514',186.96,245.08),
('20170614',61.26 ,97.67 ),
('20170714',262.98,356.16),
('20170814',89.88 ,162.38),
('20170914',250.32,381.47),
('20171014',386.06,581.96)) V([date],turnover_centrale, turnover_public))
SELECT ISNULL(CONVERT(varchar(10),[date],120),'Total') AS [date],
SUM(turnover_centrale) AS turnover_centrale,
SUM(turnover_public) AS turnover_public
FROM VTE
GROUP BY [date] WITH ROLLUP;
Thanks a lot !
My table is build like that :
https://i.imgur.com/csXl8vl.png
<br>
CLC_DATE = the date of consumption, it's corresponding to each month in a year.
<br>
CLC_PRIX_PUBLIC = the turnover public
<br>
CLC_PRIX_CENTRALE = the turnover centrale
The WHERE clause is important, beacause its the gateway from the client and his consumnption
With your solution, it doesn't work.
Related
I have a following scenario:
I created a batch job using SQL API.
final TableEnvironment tEnv = TableEnvironment.create(EnvironmentSettings.newInstance().inBatchMode().build());
I load the data from csv files, convert/aggregate it using SQL API.
At some stage I have a table:
CREATE VIEW ohlc_current_day as
SELECT
CAST(transact_time as DATE) as `day`,
instrument_id,
first_value(price) as `open`,
min(price) AS `low`,
max(price) AS `high`,
last_value(price) as `close`,
count(*) AS `count`,
sum(quantity) AS volume,
sum(quantity * price) AS turnover
FROM trades //table loaded from csv
group by CAST(transact_time as DATE), instrument_id
Now when check the results:
select * from ohlc_current_day where instrument_id=14
+------------+---------------+---------+---------+--------+---------+-------+-----------+---------------+
| day | instrument_id | open | low | high | close | count | volume | turnover |
+------------+---------------+---------+---------+--------+---------+-------+-----------+---------------+
| 2021-04-11 | 14 | 1723.0 | 1709.0 | 1743.0 | 1728.0 | 679 | 487470.0 | 8.4114803E8 |
+------------+---------------+---------+---------+--------+---------+-------+-----------+---------------+
The results are repeatable and correct (checked with reference).
Then, for futrher processing, I need ohlc values from the previous day which are already stored in a database:
CREATE TABLE ohlc_database (
`day` TIMESTAMP,
instrument_id INT,
`open` float,
`low` FLOAT,
`high` FLOAT,
`close` FLOAT,
`count` BIGINT,
volume FLOAT,
turnover FLOAT
) WITH (
'connector' = 'jdbc',
'url' = 'url',
'table-name' = 'ohlc',
'username' = 'user',
'password' = 'password'
)
Let's now merge ohlc_current_day with ohlc_database:
CREATE VIEW ohlc_raw as
SELECT * from ohlc_current_day
UNION ALL
select
CAST(`day` as DATE) as `day`,
instrument_id,
`open`,
`low`,
`high`,
`close`,
`count`,
volume,
turnover
FROM ohlc_database
WHERE `day` = '2021-04-10' //hardcoded previous day date
And check the results:
select * from ohlc_raw where instrument_id=14
+------------+---------------+--------+--------+--------+---------+-------+-----------+---------------+
| day | instrument_id | open | low | high | close | count | volume | turnover |
+------------+---------------+--------+--------+--------+---------+-------+-----------+---------------+
| 2021-04-10 | 14 | 1696.0 | 1654.0 | 1703.0 | 1691.0 | 936 | 1040888.0 | 1.74619264E9 |
| 2021-04-11 | 14 | 1723.0 | 1709.0 | 1743.0 | 1728.0 | 679 | 487470.0 | 8.4114829E8 |
+------------+---------------+--------+--------+--------+---------+-------+-----------+---------------+
results are ok, values the same as in previous select query.
Now let's order by day:
CREATE VIEW ohlc as
SELECT * from ohlc_raw ORDER BY `day`
Check the results:
select * from ohlc where instrument_id=14
+------------+---------------+-----------------+-----------------+-------------+----------------+----------------------+--------------------------------+--------------------------------+
| day | instrument_id | open | low | high | close | count | volume | turnover |
+------------+---------------+-----------------+-----------------+-------------+----------------+----------------------+--------------------------------+--------------------------------+
| 2021-04-10 | 14 | 1696.0 | 1654.0 | 1703.0 | 1691.0 | 936 | 1040888.0 | 1.74619264E9 |
| 2021-04-11 | 14 | 1729.0 | 1709.0 | 1743.0 | 1732.0 | 679 | 487470.0 | 8.4114854E8 |
+------------+---------------+-----------------+-----------------+-------------+----------------+----------------------+--------------------------------+--------------------------------+
open and close are wrong compared to previous values. They are calculated using first_value() and last_value() functions which depend on the order of elements. So my guess is that order by in last query has changed the order and this is why there are different results.
Is my understanding correct? How can I fix it?
I thought that first_value() or last_value() themself is a sort operation. When you order by in last query, the sort according to last_value() is out of order. May be you can output the result into database after union all, and then do order by date after extract data from database if possible.
I'm using SQL Server 2012. I have a table CustomerMaster. Here is some sample content:
+--------+---------------+-----------------+-------------+
| CustNo | NewMainCustNo | Longname | NoOfMembers |
+--------+---------------+-----------------+-------------+
| 3653 | 3653 | GroupId:003 | |
| 3654 | 3654 | GroupId:004 | |
| 11 | 3653 | Peter Evans | |
| 155 | 3653 | Harold Charley | |
| 156 | 3654 | David Arnold | |
| 160 | 3653 | Mickey Willson | |
| 2861 | 3653 | Jonathan Wickey | |
| 2871 | 3653 | William Jason | |
+--------+---------------+-----------------+-------------+
The NewMainCustNo for Customer records is equivalent to CustNo from Group records. Basically each customer belongs to a particular group.
My question is how to update the NoOfMembers column for group records with total number of customer belongs to a certain group.
Please share your ideas on how to do this.
Thank you...
This is the solution I came up with
update CustomerMaster
set NoOfMembers = (select count(*) from CustomerMaster m2 where m2.NewMainCustNo = CustomerMaster.CustNo and m2.CustNo <> CustomerMaster.CustNo)
where LongName like 'GroupId:%'
Check this SQL Fiddle to see the query in action.
However I disagree with your data structure. You should have a separate table for your groups. In your customer table you only need to reference the ID of the group in the group table. This makes everything (including the query above) much cleaner.
If I understand correctly, you can use a window function for the update. Here is an example with an updatable CTE:
with toupdate as (
select cm.*, count(*) over (partition by NewMainCustNo) as grpcount
from customermaster
)
update toupdate
set NoOfMembers = grpcount;
You may not have the option to do so, but I would separate groups out into their own table.
create table Groups (
GroupID int primary key,
Name varchar(200)
)
Then, change NewMainCustNo to GroupID, create, purge your customer table of groups, and go from there. Then, getting a group count would be:
select GroupID,
Name [Group Name],
COUNT(*)
from Groups g
join Customers c on
c.GroupID = g.GroupID
I've checked through here on how to use group by to count rows, but I think I am implementing it wrong, or missing something.
What I have:
Two columns with data. Machine_GroupID ( I extract the client name from this). The second column, fieldValue, contains the ship date of the Machine(I extract the year only from this).
SQL 2012 server
Example:
+------------------------------+-----------------------+
| Machine_GroupID(Client Name) | fieldValue(Ship Date) |
+------------------------------+-----------------------+
| Site1.clientA | 2015-05-07 |
| Site2.clientA | 2014-01-06 |
| Department.Site1.clientA | 2015-02-05 |
| Site1.clientB | 2014-03-04 |
| Department.Site1.ClientC | 2015-10-01 |
+------------------------------+-----------------------+
What I am trying to do:
I am trying to generate a report to show all of the workstations a client purchased in a certain year. This will end up being a report in reportviewer, or something useful to display the data to our Executive team.
Desired Report example:
Machines purchased in 2015
+---------+------------------------+
| ClientA | 2(Count of fieldValue) |
+---------+------------------------+
| ClientC | 1 |
+---------+------------------------+
Machines purchased in 2014
+---------+---+
| ClientA | 1 |
+---------+---+
| ClientB | 1 |
+---------+---+
My Code so far:
select count(*), reverse(left(reverse(Machine_GroupID) ,
charindex('.',reverse(Machine_GroupID))-1)) as Client ,
LEFT(fieldValue,4) AS "Ship Year"
from dbo.vSystemInfoManual
where fieldName = 'Ship Date'
group by fieldValue, Machine_GroupID
This code generates a table that looks like the following:
+---+----------+-----------+
| | Client | Ship Year |
+---+----------+-----------+
| 1 | ClientA | 2015 |
| 1 | ClientA | 2015 |
| 1 | ClientA | 2014 |
| 1 | ClientB | 2014 |
| 1 | ClientC | 2015 |
+---+----------+-----------+
Is there a change that I can make to my code to make this possible ? Am I trying to do too much with this query ? I am still learning SQL so any help is definitely appreciated! Thank you.
Your sample data doesn't really go along with the results you posted. Anyway, I would change the way you are getting the Client value by using the PARSENAME function:
SELECT PARSENAME(Machine_GroupID,1) Client,
LEFT(fieldValue,4) [Ship Year],
COUNT(*) N
FROM dbo.vSystemInfoManual
WHERE fieldName = 'Ship Date'
GROUP BY PARSENAME(Machine_GroupID,1),
LEFT(fieldValue,4);
have a duplicate fields and i need to update only one row how do i do this with sql 2005?
my database is as seen below:
+----------------+-------+-------------+------------------+---------------+
| Transaction_no | User | Check-In | Check-Out | barcode |
+----------------+-------+-------------+------------------+---------------+
| 01-2013 | User1 | --/--/-- | 12/28/2013 11:10 | APH009300L030 |
| 01-2013 | User1 | --/--/-- | 12/28/2013 11:10 | APH009300L030 |
| 01-2013 | User1 | --/--/-- | 12/28/2013 11:10 | APH009300L030 |
| 01-2013 | User1 | --/--/-- | 12/28/2013 11:10 | APH009300L030 |
+----------------+-------+-------------+------------------+---------------+
Try Like this
;WITH NumberedTbl AS
(
SELECT ROW_NUMBER() OVER (
PARTITION User,Check-In,Check-Out,barcode,Transaction_no
ORDER BY User,Check-In,Check-Out,barcode,Transaction_no
) AS RowNumber,
User,Check-In,Check-Out,barcode,Transaction_no
FROM tbl
)
UPDATE T
SET Check-In= GETDATE()
FROM NumberedTbl T
WHERE T.RowNumber = 1
SELECT * FROM tbl
Please see Demo here
Source
What you need in your table is a primary key column. You can just add an identity field. Then you'll be able to easily write queries like the one you need.
RAnking functions like row_number , rank , dense_rank wont work as all th field values are same and applying ORDER BY on any column after partitioninh will generate same rank for all rows.
Instead add another column habing unique values eg Identity column qfter which you can use this columm in ORDER By clause.
Sorry I know that's a rubbish Title but I couldn't think of a more concise way of describing the issue.
I have a (MSSQL 2008) table that contains telephone numbers:
| CustomerID | Tel1 | Tel2 | Tel3 | Tel4 | Tel5 | Tel6 |
| Cust001 | 01222222 | 012333333 | 07111111 | 07222222 | 01222222 | NULL |
| Cust002 | 07444444 | 015333333 | 07555555 | 07555555 | NULL | NULL |
| Cust003 | 01333333 | 017777777 | 07888888 | 07011111 | 016666666 | 013333 |
I'd like to:
Remove any duplicate phone numbers
Rearrange the telephone numbers so that anything beginning with "07" is the first phone number. If there are multiple 07's, they should be in the first fields. The order of the numbers apart from that doesn't really matter.
So, for example, after processing, the table would look like:
| CustomerID | Tel1 | Tel2 | Tel3 | Tel4 | Tel5 | Tel6 |
| Cust001 | 07111111 | 07222222 | 01222222 | 012333333 | NULL | NULL |
| Cust002 | 07444444 | 07555555 | 015333333 | NULL | NULL | NULL |
| Cust003 | 07888888 | 07011111 | 016666666 | 013333 | 01333333 | 017777777 |
I'm struggling to figure out how to efficiently achieve my goal (there are 600,000+ records in the table). Can anyone help?
I've created a fiddle if it'll help anyone play around with the scenario.
You can break up the numbers into individual rows using UNPIVOT, then reorder them based on the occurence of the '07' prefix using ROW_NUMBER(), and finally recombine it using PIVOT to end up with the 6 Tel columns again.
select *
FROM
(
select CustomerID, Col, Tel
FROM
(
select *, Col='Tel' + RIGHT(
row_number() over (partition by CustomerID
order by case
when Tel like '07%' then 1
else 2
end),10)
from phonenumbers
UNPIVOT (Tel for Seq in (Tel1,Tel2,Tel3,Tel4,Tel5,Tel6)) seqs
) U
) P
PIVOT (MAX(TEL) for Col IN (Tel1,Tel2,Tel3,Tel4,Tel5,Tel6)) V;
SQL Fiddle
Perhaps using cursor to collect all customer id and sorting the fields...traditional sorting technique as we used to do in school c++ ..lolz...like to know if any other method possible.
If you dont get any then it is the last way . It will take a long time for sure to execute.