I have a little problem with a piece of SQL code. I have a table Paiements_17_18 and I would like to create a single-line query that calculates:
the total of the Amount field,
the first date of Date_Regulation field,
the last date of Date_Regulation field,
the distinct values of N_Facture field.
All this from a sub request of the style SELECT TOP n FROM ....
I tried this:
SELECT Sum(P.Montant) AS TotalMontant,
First(P.Date_Regulation) AS PremièreDate,
Last(P.Date_Regulation) AS DernièreDate,
First(P.N_Facture) AS PremièreFacture,
Last(P.N_Facture) AS DernièreFacture,
(SELECT Count(N_Facture)
FROM (SELECT DISTINCT N_Facture FROM Paiements_17_18)) AS NombreFactures
FROM (SELECT TOP 5 Paiements_17_18.*
FROM Paiements_17_18
ORDER BY Paiements_17_18.ID_Paiement DESC) AS P;
But I get an error of "P"
(The Microsoft Access database engine cannot find the input table or
query" P" . Make sure it exists and that its name is spelled
correctly)
Can you help me please?
The 2 lines on generating the NombreFacture field is causing the error:
(SELECT Count(N_Facture)
FROM (SELECT DISTINCT N_Facture FROM Paiements_17_18)) AS
NombreFactures
Replaced the two lines. See below.
SELECT Sum(P.Montant) AS TotalMontant,
First(P.Date_Regulation) AS PremièreDate,
Last(P.Date_Regulation) AS DernièreDate,
First(P.N_Facture) AS PremièreFacture,
Last(P.N_Facture) AS DernièreFacture,
(SELECT Count(n.N_Facture_distinct)
FROM (SELECT DISTINCT N_Facture as N_facture_distinct FROM Paiements_17_18 ) AS n)
AS NombreFacture
FROM (SELECT TOP 5 Paiements_17_18.*
FROM Paiements_17_18
ORDER BY Paiements_17_18.ID_Paiement DESC) AS P;
Related
I want to get the substring out of a cell value wrt following eg-
Input: "J.H.Ambani.School"-----------School
Output: "H.Ambani"-----------------MidName
That is all the text that comes between the first and the last dots. Length of string or number of dots in string can be any. I am trying to form a query for above input column "School" to get the output column "MidName".What can be the sql query for it?
For Oracle Database:
SELECT
REGEXP_REPLACE(yourColumn, '^[^.]*.|.[^.]*$', '') AS yourAlias
FROM yourTable
If is correctly understood your problem by your statement
"That is all the text that comes between the first and the last dots". Then below is solution to your problem is as given below. Below is working solution in SQL SERVER, for other databases i could not check because of lack of time.
#SourceString : this is your input
#DestinationString : this is your output
declare #SourceString varchar(100)='J.H.Ambani.School'
declare #DestinationString varchar(100)
;with result as
(
select ROW_NUMBER()over (order by (select 100))SNO,d from(
select t.c.value('.','varchar(100)')as d from
(select cast('<a>'+replace(#SourceString,'.','</a><a>')+'</a>' as xml)data)as A cross apply data.nodes('/a') as t(c))B
)
select #DestinationString=COALESCE(#DestinationString+'.','')+ISNULL(d,'') from result where SNO>(select top 1 SNO from result order by SNO)
and SNO<(select top 1 SNO from result order by SNO desc)
select #DestinationString
I have a basic query which shows what the latest product to be put in each location (FVTank) is:
SELECT TOP 1
T0.[DateTime],
T0.[TankName],
T1.[Item]
FROM
t005_pci_data T0
INNER JOIN t001_fvbatch T1 ON T1.[FVBatch] = T0.[FVBatch]
WHERE
T0.[TankName] = 'FV101'
UNION
SELECT TOP 1
T0.[DateTime],
T0.[TankName],
T1.[Item]
FROM
t005_pci_data T0
INNER JOIN t001_fvbatch T1 ON T1.[FVBatch] = T0.[FVBatch]
WHERE
T0.[TankName] = 'FV102'
[...etc...]
ORDER BY
T0.[DateTime] DESC
Which gives a result like this:
What I'd like to do is create a summary page on SSRS which would display all the locations which currently hold each item. Ideally it would look something like this:
There are 50 locations and 7 main items so I need it to have 8 headers (one additional one for "other".)
Is there a way to do this in SSRS? Or is there a better solution by doing it in SQL?
Thank you.
Add an additional column to your dataset that calculates a row number for each Item, ordered by the DateTime field:
row_number() over (partition by Item order by DateTime desc) as rn
Judging by your source query in your question, this may be best included as a wrapping select around your final query:
select DateTime
,TankName
,Item
,row_number() over (partition by Item order by DateTime desc) as rn
from(
<Your original query here>
) a
You can then use this as your row group, as without one you will not get the top aligned format you are after in each Item x column. Remember to delete the rn column but keep the grouping:
When you run this report you will get the following format (I didn't bother typing out all your data into my dataset query, hence the missing values):
This question already has answers here:
Select first row in each GROUP BY group?
(20 answers)
Closed 8 years ago.
I am writing a program for amateur radio. Some callsigns will appear more than once in the data but the qsodate will be different. I only want the first occurrence of a call sign after a given date.
The query
select distinct
a.callsign,
a.SKCC_Number,
a.qsodate,
b.name,
a.SPC,
a.Band
from qso a, skccdata b
where SKCC_Number like '%[CTS]%'
AND QSODate > = '2014-08-01'
and b.callsign = a.callsign
order by a.QSODate
The problem:
Because contacts occur on different dates, I get all of the contacts - I have tried adding min(a.qsodate) to get only the first but then I run into all sorts of issues regarding grouping.
This query will be in a stored procedure, so creating temp tables or cursors will not be a problem.
You can use the ROW_NUMBER() to get the first row with the first date, like this:
WITH CTE
AS
(
select
a.callsign,
a.SKCC_Number,
a.qsodate,
b.name,
a.SPC,
a.Band,
ROW_NUMBER() OVER(PARTITION BY a.callsign ORDER BY a.QSODate) AS RN
from qso a,skccdata b
where SKCC_Number like '%[CTS]%'
AND QSODate > = '2014-08-01'
and b.callsign = a.callsign
)
SELECT *
FROM CTE
WHERE RN = 1;
ROW_NUMBER() OVER(PARTITION BY a.callsign ORDER BY a.QSODate) will give you a ranking number for each group of callsign ordered by QSODate, then the WHERE RN = 1 will eliminate all the rows except the first one which has the minimum QSODate.
Have you tried starting your query with SELECT TOP 1 ...(fields) Then you will only get one row. You can use TOP x .... for x number of rows, or TOP 50 PERCENT for the top half of the rows, etc. Then you can eliminate DISTINCT in this case
EDIT: misunderstood question. How about this?
select
a.callsign,
a.SKCC_Number,
a.qsodate,
(SELECT TOP 1 b.name FROM skccdata b WHERE b.callsign = a.callsign) as NAME,
a.SPC,
a.Band
from qso a
where SKCC_Number like '%[CTS]%'
AND QSODate > = '2014-08-01'
GROUP BY a.QSODate, a.callsign, a.SKCC_Number, a.SPC, a.Band
order by a.QSODate
and add callsign to your where clause to isolate callsigns
I have a postgresql query like this:
with r as (
select
1 as reason_type_id,
rarreason as reason_id,
count(*) over() count_all
from
workorderlines
where
rarreason != 0
and finalinsdate >= '2012-12-01'
)
select
r.reason_id,
rt.desc,
count(r.reason_id) as num,
round((count(r.reason_id)::float / (select count(*) as total from r) * 100.0)::numeric, 2) as pct
from r
left outer join
rtreasons as rt
on
r.reason_id = rt.rtreason
and r.reason_type_id = rt.rtreasontype
group by
r.reason_id,
rt.desc
order by r.reason_id asc
This returns a table of results with 4 columns: the reason id, the description associated with that reason id, the number of entries having that reason id, and the percent of the total that number represents.
This table looks like this:
What I would like to do is only display the top 10 results based off the total number of entries having a reason id. However, whatever is leftover, I would like to compile into another row with a description called "Other". How would I do this?
with r2 as (
...everything before the select list...
dense_rank() over(order by pct) cause_rank
...the rest of your query...
)
select * from r2 where cause_rank < 11
union
select
NULL as reason_id,
'Other' as desc,
sum(r2.num) over() as num,
sum(r2.pct) over() as pct,
11 as cause_rank
from r2
where cause_rank >= 11
As said above Limit and for the skipping and getting the rest use offset... Try This Site
Not sure about Postgre but SELECT TOP 10... should do the trick if you sort correctly
However about the second part: You might use a Right Join for this. Join the TOP 10 Result with the whole table data and use only the records not appearing on the left side. If you calculate the sum of those you should get your "Sum of the rest" result.
I assume that vw_my_top_10 is the view showing you the top 10 records. vw_all_records shows all records (including the top 10).
Like this:
SELECT SUM(a_field)
FROM vw_my_top_10
RIGHT JOIN vw_all_records
ON (vw_my_top_10.Key = vw_all_records.Key)
WHERE vw_my_top_10.Key IS NULL
In my application I use SELECT TOP 12 * clause to select top 12 records from database and show it to user. In another case I have to show the same result one by one. So I use SELECT TOP 1 * clause,rest of the query is same. I used Sql row_number() function to select items one by on serially.
The problem is SELECT TOP 1 * doesn't return me same row as I get in SELECT TOP 12 *. Also the result set of SELECT TOP 12 * get changed each time I execute the query.
Can anybody explain me why the result is not get same in SELECT TOP 12 * and SELECT TOP 1 *.
FYI: here is my sql
select distinct top 1 * from(
select row_number() over ( ORDER BY Ratings desc ) as Row, * from(
SELECT vw.IsHide, vw.UpdateDate, vw.UserID, vw.UploadPath, vw.MediaUploadID, vw.Ratings, vw.Caption, vw.UserName, vw.BirthYear, vw.BirthDay, vw.BirthMonth, vw.Gender, vw.CityProvince, vw.Approved
FROM VW_Media as vw ,Users as u WITH(NOLOCk)
WHERE vw.IsHide='false' and
GenderNVID=5 and
vw.UserID=u.UserID and
vw.UserID not in(205092) and
vw.UploadTypeNVID=1106 and
vw.IsDeleted='false' and
vw.Approved = 1 and
u.HideProfile=0 and
u.StatusNVID=126 and
vw.UserID not in(Select BlockedToUserID from BlockList WITH(NOLOCk) where UserID=205092) a) totalres where row >0
Thanks in Advance
Sachin
When you use SELECT TOP, you must use also the ORDER BY clause to avoid different results every time.
For performance resons, the database is free to return the records in any order it likes if you don't specify any ordering.
So, you always have to specify in which order you want the records, if you want them in any specific order.
Up to some version of SQL Server (7 IIRC) the natural order of the table was preserved in the result if you didn't specify any ordering, but this feature was removed in later versions.