Self joining columns from the same table with calculation on one column not displaying column name - sql

I am fairly new to SQL and having issues figuring out how to solve the simple issue below. I have a dataset I am trying to self-join, I am using (b.calendar_year_number -1) as one of the columns to join. I applied a calculation of -1 with the goal of trying to match values from the previous year. However, it is not working as the resulting column shows (No column name) with a screenshot attached below. How do I change the alias to b.calendar_year_number after the calculation?
Code:
SELECT a.day_within_fiscal_period,
a.calendar_month_name,
a.cost_period_rolling_three_month_start_date,
a.calendar_year_number,
b.day_within_fiscal_period,
b.calendar_month_name,
b.cost_period_rolling_three_month_start_date,
(b.calendar_year_number -1)
FROM [data_mart].[v_dim_date_consumer_complaints] AS a
JOIN [data_mart].[v_dim_date_consumer_complaints] AS b
ON b.day_within_fiscal_period = a.day_within_fiscal_period AND
b.calendar_month_name = a.calendar_month_name AND
b.calendar_year_number = a.calendar_year_number

I am using (b.calendar_year_number -1) as one of the columns to join.
Nope, you're not. Look at your join statement and you'll see the third condition is:
b.calendar_year_number = a.calendar_year_number
So just change that to include the calculation. As far as the 'no column name' issue, you can use colname = somelogic syntax or somelogic as colname. Below, I used the former syntax.
select a.day_within_fiscal_period,
a.calendar_month_name,
a.cost_period_rolling_three_month_start_date,
a.calendar_year_number,
b.day_within_fiscal_period,
b.calendar_month_name,
b.cost_period_rolling_three_month_start_date,
bCalYearNum = b.calendar_year_number
from [data_mart].[v_dim_date_consumer_complaints] a
left join [data_mart].[v_dim_date_consumer_complaints] b
on b.day_within_fiscal_period = a.day_within_fiscal_period
and b.calendar_month_name = a.calendar_month_name
and b.calendar_year_number - 1 = a.calendar_year_number;

You could use the analytical function LAG/LEAD to get your required result, no self-join necessary:
select a.day_within_fiscal_period,
a.calendar_month_name,
a.cost_period_rolling_three_month_start_date,
a.calendar_year_number,
old_cost_period_rolling_three_month_start_date =
LAG(cost_period_rolling_three_month_start_date) OVER
(PARTITION BY calendar_month_name, day_within_fiscal_period
ORDER BY calendar_year_number),
old_CalYearNum = LAG(calendar_year_number) OVER
(PARTITION BY calendar_month_name, day_within_fiscal_period
ORDER BY calendar_year_number)
from [data_mart].[v_dim_date_consumer_complaints] a

Related

Why my SQL query does not apply my where not equal condition?

I used a CTE (temp table) to compute data through semesters. With my query, I want to compare if my data (already aggregated) are equal to my sum computed in my CTE. However, when using WHERE data_already_aggregated <> data_computed I got a result where my results in those columns are equal. I tried to use =! as well, and also =. Last option worked, but not the way I want.
Here my code:
WITH trimestriel AS(
SELECT "donnéestrim".annee,
"donnéestrim".trimestre,
"donnéestrim".codescpi,
scpi.scpi,
"donnéestrim"."rd_t",
SUM("donnéestrim".rd_t) OVER (PARTITION BY "donnéestrim".annee, "donnéestrim".codescpi) AS "trim_sum_totalYear_rd_t",
row_number() over (partition BY scpi.codescpi, annee) AS "row_number"
FROM "donnéestrim"
LEFT JOIN scpi ON scpi.codescpi = "donnéestrim".codescpi
ORDER BY "donnéestrim".annee)
SELECT "annuel".codescpi,
scpi.scpi ,
"annuel".annee,
trimestriel."trimestre",
"annuel".revdisavpl AS "annuel_revdisavpl",
"trim_sum_totalYear_rd_t",
"rd_t" AS "trim_rd_t"
FROM "annuel"
LEFT JOIN scpi ON scpi.codescpi = "annuel".codescpi
LEFT JOIN trimestriel ON trimestriel.codescpi = "annuel".codescpi AND trimestriel.annee=annuel.annee
WHERE "annuel".annee = '2018' and scpi.codescpi = '129' and "annuel".revdisavpl != "trim_sum_totalYear_rd_t"
result
As #JNevill suggested, it's a data type problem. A double precision type only display the data with its specific parameters, but can store more information if casted. I cast it to real, and I can saw the gaps between my data.

How can I do a SQL join to get a value 4 tables farther from the value provided?

My title is probably not very clear, so I made a little schema to explain what I'm trying to achieve. The xxxx_uid labels are foreign keys linking two tables.
Goal: Retrieve a column from the grids table by giving a proj_uid value.
I'm not very good with SQL joins and I don't know how to build a single query that will achieve that.
Actually, I'm doing 3 queries to perform the operation:
1) This gives me a res_uid to work with:
select res_uid from results where results.proj_uid = VALUE order by res_uid asc limit 1"
2) This gives me a rec_uid to work with:
select rec_uid from receptor_results
inner join results on results.res_uid = receptor_results.res_uid
where receptor_results.res_uid = res_uid_VALUE order by rec_uid asc limit 1
3) Get the grid column I want from the grids table:
select grid_name from grids
inner join receptors on receptors.grid_uid = grids.grid_uid
where receptors.rec_uid = rec_uid_VALUE;
Is it possible to perform a single SQL that will give me the same results the 3 I'm actually doing ?
You're not limited to one JOIN in a query:
select grids.grid_name
from grids
inner join receptors
on receptors.grid_uid = grids.grid_uid
inner join receptor_results
on receptor_results.rec_uid = receptors.rec_uid
inner join results
on results.res_uid = receptor_results.res_uid
where results.proj_uid = VALUE;
select g.grid_name
from results r
join resceptor_results rr on r.res_uid = rr.res_uid
join receptors rec on rec.rec_uid = rr.rec_uid
join grids g on g.grid_uid = rec.grid_uid
where r.proj_uid = VALUE
a small note about names, typically in sql the table is named for a single item not the group. thus "result" not "results" and "receptor" not "receptors" etc. As you work with sql this will make sense and names like you have will seem strange. Also, one less character to type!

Assistance with SQL Query (aggregating)

I have a requirement to create a Sales report and I have a sql query:
SELECT --top 1
t.branch_no as TBranchNo,
t.workstation_no as TWorkstation,
t.tender_ref_no as TSaleRefNo,
t.tender_line_no as TLineNo,
t.tender_code as TCode,
T.contribution as TContribution,
l.sale_line_no as SaleLineNo
FROM TENDER_LINES t
LEFT JOIN SALES_TX_LINES l
on t.branch_no = l.branch_no and t.workstation_no = l.workstation_no and t.tender_ref_no = l.sale_tx_no
where l.sale_tx_no = 2000293 OR l.sale_tx_no = 1005246 --OR sale_tx_no = 1005261
order by t.tender_ref_no asc,
l.sale_line_no desc
The results of the query look like the following:
The results I am trying to achieve is:
With only 1 line for transaction 2 either SaleLineNo 1 or 2, while still have=ing both lines for transaction 1 because the TCode is different.
Thanks
I am using SSQL2012.
Not exactly sure on what data you have, but you might want to try
GROUP BY TlineNo, TCode ...
But you have to keep a look on not to group by something that would result in duplicate contribution values.
You can use the ROW_NUMBER function that allows to partition the rows in groups, and number the lines inside each group starting by one. If you choose the right columns to define the partition, and keep only the rows with "row_number = 1`, you have solved the first part of your problem, i.e. discarding the lines that don't have to appear in the report. (See the sample sin the linked documentation, they're quite clear).
Once you have solved this problem, you simply have to repeat what you're doing, but on the result of this data, instead of the original data. You can use a view, a CTE, or a subselect to achieve your result, i.e.
With view:
CREATE VIEW FilteredData AS -- here the rank function query, then selct from the view
SELECT --here your current query --
FROM FilteredData
With CTE
WITH -- here the rank function query
SELECT -- your current querym, from the CTE
With subselect
SELECT -- your current query
FROM (SELECT FROM -- here the rank function query -- )
Appreciate your assistance with my query. After playing around, I have found a solution that works just as I want. It is as below: I did a Group by as hinted by #Yogesh86 on a few fields.
SELECT
MAX(t.branch_no) as TBranchNo,
Max(t.workstation_no) as TWorkstation,
t.tender_ref_no as TSaleRefNo,
Max(t.tender_line_no) as TLineNo,
t.tender_code as TCode,
MAx(T.contribution) as TContribution,
MAX(l.sale_line_no) as SaleLineNo
FROM TENDER_LINES t
LEFT JOIN SALES_TX_LINES l
on t.branch_no = l.branch_no and t.workstation_no = l.workstation_no and t.tender_ref_no = l.sale_tx_no
where l.sale_tx_no = 2000293 OR l.sale_tx_no = 1005246 --OR sale_tx_no = 1005261
GROUP BY
t.tender_ref_no,
t.tender_line_no,
t.tender_code

Using Case Statement to replace value in one field based on value in a seperate field

I'm creating a report in SSRS and I can't use the IIF statement within the report to get the following done. I'm getting aggregate errors when I try to sum within the SSRS report.
`IIF(Fields!Period=0,0,IIF(Period=13,0,Balance/12))`
Works fine up until the moment I try to Sum.. get a silly aggregate error "Aggregate functions other than First, Last, Previous, Count, and Count Distinct can only aggregate data of a single data type"... These are all integers.
Basically I have a value in Master.Balance that I need to divide by 12 only when Secondary.Period equals 0 or 13. If Secondary.Period equals 0 or 13 then the value should be 0. I know my problem has to do with including the relationship between the tables, but I just don't know how to write that in.
Here is what I'm trying to use:
`CASE
WHEN Secondary.Period=0 OR Secondary.Period=13
THEN 0
ELSE Master.Balance/12
End As BudByPer`
Here is how the two tables are related to each other:
`FROM Master LEFT OUTER JOIN Secondary
ON Master.Project = Secondary.Project
AND Master.object = Secondary.object
AND Master.org = Secondary.org
`
How do I get the above into this:
SELECT DISTINCT Master.Project, Master.Object, Master.Fund, Master.Segment, Master.Balance, Secondary.project, Secondary.object, Secondary.org, Secondary.Period, Secondary.object, Secondary.Project.
FROM Master LEFT OUTER JOIN Secondary
ON Master.Project = Secondary.Project
AND Master.object = Secondary.object
AND Master.org = Secondary.org
WHERE (Master.object>=600000)
ORDER BY [Master.Fund]
You just need a select, it looks fine to me...
SELECT
Master.account,
Master.segment,
Secondary.desc,
Secondary.bud,
Segment.Num,
Segment.office,
CASE
WHEN Secondary.Period=0 OR Secondary.Period=13 THEN 0
ELSE Master.Balance/12
End As BudByPer
FROM Master
LEFT JOIN Secondary
ON Master.Project = Secondary.Project
AND Master.object = Secondary.object
AND Master.org = Secondary.org

Gettin a value from a table and using in the same query

SELECT (h.horario), h.codigo
FROM horarios as h
JOIN horario_turma as h_t
ON(h.codigo != h_t.cd_horario)
WHERE h_t.cd_turma = 'HTJ009'
AND h_t.cd_dia = 2
AND h.cd_turno = 1
I'm trying to figure out if there's a possibility to get the h.cd_turnovalue from another table and use in the same query, beacuse this value is gonna be variable. So, I'd have to get this value from a query, then pass the value to PHP and do another query with this value. Is there a way to do that in the same query?
There's a table called turmas(codigo, cd_turno). I'll have the codigovalue, in this case HTJ009, and I'd like to select the cd_turno value.
Query used to get the value:
SELECT cd_turno FROM turmas WHERE codigo='HTJ009'
You can use a subquery, like so:
SELECT (h.horario), h.codigo
FROM horarios as h
JOIN horario_turma as h_t
ON(h.codigo != h_t.cd_horario)
WHERE h_t.cd_turma = 'HTJ009'
AND h_t.cd_dia = 2
AND h.cd_turno = (SELECT cd_turno FROM turmas WHERE codigo='HTJ009')
In this case, remember that it is important for the subquery to return only one result, otherwise you'll encounter an error. If you do see such an error, you may have to tweak the subquery to ensure only one result is returned.
Check this out for Postgres subquery documentation
SELECT (h.horario), h.codigo
FROM horarios as h
JOIN horario_turma as h_t
ON(h.codigo = h_t.cd_horario)
WHERE h_t.cd_turma = 'HTJ009'
AND h_t.cd_dia = 2
AND h.cd_turno = 1 and h_t.cd_horario is null