Sorting rows in cross query Access SQL - sql

I have a cross query in Access with an SQL:
TRANSFORM Tab1.Income AS Income
SELECT Tab1.Month
FROM Tab1
GROUP BY Tab1.Month
PIVOT Tab1.Group;
Months are string, not a number, and are in alphabetical order. I want to sort them manually.
In the normal query, I used a Switch() function which works perfectly. But in the cross query I've got an alert that ORDER BY and GROUP BY are mutually exclusive.
I would be grateful for any idea, how to sort them in query. However, if it's not possible, maybe they can be sorted in the report because this is more important.

Options:
calculate month number field to use as primary group criteria, include it along with month name as Row Headers and if this is a multi-year dataset perhaps should also include year as a Row Header - hopefully there is a full date field available to extract date parts from
report design can use expression to dictate sort order
Month is a reserved word and advise not to use reserved words as object names.

Related

I need to retrieve a column from already retrieved column from a table

I had a table which has a column like this which i retrieved from this query
select distinct HDD_WP_RPTNG_AS_OF_SID
from wcadbo.WCA_MDW_D_HLDNGS_DATE
order by HDD_WP_RPTNG_AS_OF_SID desc;
Table:
HDD_WP_RPTNG_AS_OF_SID
20210501
20210430
20210429
20210428
It contains dates in integer format.
I wrote a query to retrieve another column of these dates in date format and I named column as AS_OF_DATE - like this:
SELECT DISTINCT
HDD_WP_RPTNG_AS_OF_SID,
to_date(HDD_WP_RPTNG_AS_OF_SID,'YYYYMMDD') AS_OF_DATE
FROM
WCADBO.WCA_MDW_D_HLDNGS_DATE
ORDER BY
HDD_WP_RPTNG_AS_OF_SID DESC;
Result set:
HDD_WP_RPTNG_AS_OF_SID AS_OF_DATE
----------------------------------
20210501 01-MAY-21
20210430 30-APR-21
20210429 29-APR-21
20210428 28-APR-21
Now I need another column as Display_Date in char type which gives LastAvailableDate for latest date in previous column or gives Date in char type for all other dates like this
I wrote this query but not working:
SELECT
HDD_WP_RPTNG_AS_OF_SID,
AS_OF_DATE,
Display_date
FROM
(SELECT DISTINCT
HDD_WP_RPTNG_AS_OF_SID,
to_date(HDD_WP_RPTNG_AS_OF_SID,'YYYYMMDD') AS_OF_DATE
FROM
WCADBO.WCA_MDW_D_HLDNGS_DATE
ORDER BY
HDD_WP_RPTNG_AS_OF_SID DESC)
WHERE
Display_Date = (CASE
WHEN AS_OF_DATE = '01-MAY-21'
THEN 'Last_Available_date'
ELSE TO_CHAR(AS_OF_DATE, 'MON DD YYYY')
END);
Finally I need three columns, one is already in table but modified a bit. Other two are temporary ones(AS_OF_DATE and Display_Date) that i need to retrieve.
I'm a beginner in SQL and couldn't figure out how to retrieve column from another temporary column..
Kindly help, Thank you.
BTW I was doing it in Oracle SQL Developer
It looks like you want something like this
SELECT
subQ.HDD_WP_RPTNG_AS_OF_SID,
subQ.AS_OF_DATE,
(CASE
WHEN subQ.AS_OF_DATE = date '2021-05-01'
THEN 'Last_Available_date'
ELSE TO_CHAR(subQ.AS_OF_DATE, 'MON DD YYYY')
END) Display_date
FROM
(SELECT DISTINCT
tbl.HDD_WP_RPTNG_AS_OF_SID,
to_date(tbl.HDD_WP_RPTNG_AS_OF_SID,'YYYYMMDD') AS_OF_DATE
FROM
WCADBO.WCA_MDW_D_HLDNGS_DATE tbl) subQ
ORDER BY
subQ.HDD_WP_RPTNG_AS_OF_SID DESC
Comments
If you want to add computed columns, that is done in the projection (the select list)
Always compare dates to dates and strings to strings. So in your case statement, compare the date as_of_date against another date. In this case I'm using a date literal. You could also call to_date on a string parameter.
If you want the results of the query ordered by a particular column, you want that order by applied at the outermost layer of the query, not in an inline view.
You basically always want to use aliases when referring to any column in a query. It's less critical in situations where everything is coming from one table but as soon as you start referencing multiple tables in a query, it becomes annoying to look at a query and not sure where a column is coming from. Even in a query like this where there is an inline view and an outer query, it makes it easier to read the query if you're explicit about where the columns are coming from.
Do you really need the distinct? I kept it because it was a part of the original query but I get antsy whenever I see a distinct particularly from people learning SQL. Doing a distinct is a relatively expensive operation and it is very commonly used to cover up an underlying issue in the query (i.e. that you're getting multiple rows because some other column you aren't showing has multiple values) that ought to be addressed correctly (i.e. by adding an additional predicate to ensure that you're only getting each hdd_wp_rptg_as_of_sid once).
Storing dates as strings in tables (as is done apparently with hdd_wp_rptg_as_of_sid) is a really bad practice. If one person writes one row to the table where the string isn't in the right format, your query will suddenly stop working and start throwing errors, for example.

Bigquery - remove duplicates of certain columns, but not all

I have two tables I am left joining together. The first tables has transnational level detail, causing the key I join to the second table to duplicate. When I left join the second table, the measure "company_spend" is highly inflated.
I need a way to keep only a single value of the duplicated data, and my thought was to run a distinct function on only those columns, but I am not seeing that Bigquery supports distinct functions on only a few columns, but not all.
SELECT UPPER(cwnextt.Current_Contract_Number) AS Current_Contract_Number,
UPPER(cwnextt.Replacement_Contract_Number) AS Replacement_Contract_Number,
UPPER(cwnextt.Current_Contract_Name) AS Current_Contract_Name,
UPPER(cwnextt.Supplier_Top_Parent_Entity_Code) AS Supplier_Top_Parent_Entity_Code,
UPPER(cwnextt.Supplier_Top_Parent_Name) AS Supplier_Top_Parent_Name,
UPPER(cwnextt.company_Entity_Code) AS company_Entity_Code,
UPPER(cwnextt.Facility_Name) AS Facility_Name,
smart.company_Spend AS companySpend
FROM `test_etl_field.contracts_with_member_entity_codes_test_view_2` cwnextt
--this table is what is causing the below table to duplicate,
--but I need all of this data AS well in its current format.
LEFT JOIN `test.trans_analysis` tsa
ON TRIM(UPPER(cwnextt.company_entity_code)) = TRIM(UPPER(tsa.company_entity_code))
AND TRIM(UPPER(cwnextt.Supplier_Top_Parent_Entity_Code)) = TRIM(UPPER(tsa.manufacturer_top_parent_entity_code))
AND TRIM(UPPER(cwnextt.Current_Contract_Name)) = TRIM(UPPER(tsa.contract_category))
AND cwnextt.spend_period_yyyyqmm = tsa.spend_period_yyyyqmm
--this table contains "company_spend" which is now duplicated
LEFT JOIN `test_etl_field.ecr_smart_data` smart
ON smart.company_entity_code = cwnextt.company_entity_code
AND (smart.contract_number = cwnextt.current_contract_number
OR smart.contract_number = cwnextt.replacement_contract_number)
AND smart.month_key = cwnextt.spend_period_yyyyqmm
If something can be created that will keep company_spend from duplicating on the second left join, that is what I am after.
Not sure to understand all the details of your problem but here's a fact from BigQuery doc :
SELECT DISTINCT
A SELECT DISTINCT statement discards duplicate rows
and returns only the remaining rows.
You can't apply DISTINCT on specific columns because it doesn't make sense. Let's say you have 4 columns and call DISTINCT on 3 columns, what is SQL supposed to do with the last one ?
You must tell SQL which value to keep for the remaining column and GROUP BY is the right solution here.
So if you want to:
Remove a column that has been duplicated : Just adjust your SELECT to get only the columns you want
Remove lines that have the same value in specific columns : I would suggest a GROUP BY on the targeted column and taking the aggregation you want (first, avg, sum or whatever) for the remaining ones.
Remove the value from a row if another row has the same : You may not want to do that. A row has to keep its value and you won't get it back. Besides, same problem, which row do you want to keep ?
Hope this helps ! Feel free to give clarification on your problem if you want more specific answers.
While I couldn't resolve this issue in SQL, I used Tableau via a FIXED LOD to aggregate the data passed duplicates so the end user could visualize the output with accuracy. Not ideal, but the SQL route wasn't make sense.

How would I use a CURSOR to iterate through a list of values to do a calculation for each value?

I have searched and searched for a way to do what I'm trying to do, but I haven't found a solution yet. I have dates stored in a table like so:
Dates Code Sum
1-15-2015 AAA (to be calculated)
2-2-2016 BBB (to be calculated)
11-23-2015 CCC (to be calculated)
The sum for each record in the table is calculated based on the date in the Date column. I want to use the date from the Date column as a parameter of sorts to do the calculation for each record in the table. I assume a CURSOR would be the best approach, but I am new to SQL and I don't how to implement such functionality. For example's sake, you can totally make up the sum calculation. It's trivial, anyway. I have looked at several examples elsewhere, but I've had no luck. Any help is greatly appreciated.
The Sum Calculation
The sum is calculated by pulling values out of another database, via a pass-through query, within a date range. The date range is determined by the date in the Dates column of the example table. The date range is the date value in the Dates column to today's date (GetDate()). All I need to know how to do is change the left date to the date in the Dates column for each record in the sample table. Efficiency is key.
My answer will be very generic, but you'll need to do either an OUTER APPLY or a CROSS APPLY depending on if you want to filter NULL values or not.
The syntax would look something similar to this:
Select A.Dates, A.Code, X.Sum
From YourTable A
Outer Apply
(
Select Sum(B.StuffToSum) As Sum
From OtherDatabase.OtherSchema.OtherTable B
Where B.Date Between A.Dates And GetDate()
) X
Your OUTER APPLY logic should match the actual logic you're using, I'm just using this as an example showing how you can get a date range from the Date in the first table to GETDATE().
Using an OUTER APPLY, if there are no values in your other table that fall in that date range, it will return NULL. In the case of a CROSS APPLY, the entire record will be filtered out (this behaviour is similar to that of INNER and OUTER JOINS).

Wild Card Character to extract all the columns in Sql Server Pivot column

While creating PIVOT table in Sql Server i need to mention the column in hard coded manner but now i have to write down all the columns. Now from my code you can see i can't predict what a month user might choose and i want to show that months all dates.
pivot
(
sum(column1)
for Date in (
[04-18-2014], [04-19-2014]
)
Here i have to mention that [04-18-2014], [04-19-2014] are the column names that i have to use. how can i extract all the columns whatever present in Date column like a wild card character or something else which can help me to solve this problem.

Need to group on expression in column in tablix

I have a report that is grouped on several fields from my dataset. However, one of the columns in my tablix is an expression, NOT a dataset field and I don't see that expression as an option to pick when I try to add it to the detail grouping.
basically, I'm pulling the vendor's name on each order. For one particular type of order (flower seed) one order can have several different vendors that actually supply the seed, but since it comes from us, WE really are the vendor. So, in the column for vendor name in my tablix, I have an expression: =IIF(Fields!major_grp.Value = "S","Seeds",Fields!vend_desc.Value) so that if it's a seed order, I make the vendor description "Seeds", otherwise I use whatever is the real value in the Field!vend_desc.value.
I need to be able to add new group expression on my calculated value, not the actual value from the dataset but it's not giving me my expression as an option to pick, just the dataset value "vend_desc". Is it possible to group on an expression in a column of a tablix?
the only other thing I thought might be possible is to calculate the value of the vendor description in my SQL select statement in the dataset that pulls the data initially, but the Select statement I'm using is EXTREMELY complex and I'd hate to make it even muddier....
You can create group on expression, in the group properties, where it says group on, add your expression there.
You can further look into the following links
http://technet.microsoft.com/en-us/library/dd220419.aspx
http://technet.microsoft.com/en-us/library/ms170712.aspx