Need to group on expression in column in tablix - sql

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

Related

How to add column to an existing table and calculate the value

Table info:
I want to add new column and calculated the different of the alarmTime column with this code:
ALTER TABLE [DIALinkDataCenter].[dbo].[DIAL_deviceHistoryAlarm]
ADD dif AS (DATEDIFF(HOUR, LAG((alarmTime)) OVER (ORDER BY (alarmTime)), (alarmTime)));
How to add the calculation on the table? Because always there's error like this:
Windowed functions can only appear in the SELECT or ORDER BY clauses.
You are using the syntax for a generated virtual column that shows a calculated value (ADD columnname AS expression).
This, however, only works on values found in the same row. You cannot have a generated column that looks at other rows.
If you consider now to create a normal column and fill it with calculated values, this is something you shouldn't do. Don't store values redundantly. You can always get the difference in an ad-hoc query. If you store this redundantly instead, you will have to consider this in every insert, update, and delete. And if at some time you find rows where the difference doesn't match the time values, which column holds the correct value then and which the incorrect one? alarmtime or dif? You won't be able to tell.
What you can do instead is create a view for convenience:
create view v_dial_devicehistoryalarm as
select
dha.*,
datediff(hour, lag(alarmtime) over (order by alarmtime), alarmtime) as dif
from dial_devicehistoryalarm dha;
Demo: https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=b7f9b5eef33e72955c7f135952ef55b5
Remember though, that your view will probably read and sort the whole table everytime you access it. If you query only a certain time range, it will be faster hence to calculate the differences in your query instead.

Sorting rows in cross query Access 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.

DAX - Calcuate a many to many mapping?

I'm trying to build a calculated table, containing the mapping between different datasets. The keys I'm using to do the lookup can be repeated and I would like to generate the list of all possible combinations. In SQL, this would be a join which would generate additional rows. I'm looking to do the same in DAX, with a calculated table, however LOOKUPVALUE can only return one row and will error if it finds more than one match.
A table of multiple values was supplied where a single value was expected
I feel like it could be possible with summarise columns and a virtual relationship, however when trying this, I also get an error
=SUMMARIZECOLUMNS (
Label[LabelText],
User[Dim_CustomerUser_Skey],
Computer[Dim_Computer_Skey]
,FILTER ( Computer, Label[Device] = Computer[Device name])
, FILTER ( User, Label[UserName] =User[UserName])
)
but this also gives:
Calculated table 'CalculatedTable 1': A single value for column 'Device' in table 'Label' cannot be determined. This can happen when a measure formula refers to a column that contains many values without specifying an aggregation such as min, max, count, or sum to get a single result
How to I produce a calculated table for a many to many?
In SQL, there are Joins. Luckily for us DAX provide joins between tables.
But first of all, what function to use for what? Here it is:
Left Outer: GENERATEALL, NATURALLEFTOUTERJOIN
Right Outer: GENERATEALL, NATURALLEFTOUTERJOIN
Full Outer: CROSSJOIN, GENERATE, GENERATEALL
Inner: GENERATE, NATURALINNERJOIN
Left Anti: EXCEPT
Right Anti: EXCEPT
Visit : https://www.sqlbi.com/articles/from-sql-to-dax-joining-tables/

How does SQL SELECT statement work?

I created a table with id as primary key, firstname, lastname, email as fields. I issued the following query:
"SELECT email,COUNT(email) FROM mytable;"
The result had the first value for email i.e from the first record and the total number of values from the column 'email'. Why did it not display all the different values for email from different records?
https://dev.mysql.com/doc/refman/8.0/en/group-by-handling.html says:
Without GROUP BY, there is a single group and it is nondeterministic which name value to choose for the group.
Like with any grouping query, the COUNT(*) returns the count of rows in the group, and reduces the result to one row per group.
But since you don't have any GROUP BY clause, the whole table is treated as one big group, and the result only returns one row.
The email column returns one of the email values in the group. Technically this value is chosen arbitrarily from one of the rows in the group.
In practice, MySQL's implementation chooses the value from the first row read from the group, the order of which depends on which index was used to scan the table. Though this behavior of picking the first row is not documented and they make no guarantee to make this behavior the same from version to version.
It's better to avoid depending on queries that return an arbitrary, implementation-dependent value. It makes your code harder to maintain, because there's a risk it will change if you upgrade MySQL and they change their undocumented behavior.
To protect you from making these sorts of arbitrary queries, newer versions of MySQL enforce an SQL mode called ONLY_FULL_GROUP_BY. That option makes it an error to run a query like that one you show. For what it's worth, the query is already an error in most other brands of SQL database.

How to get data based on two columns from same table in SQL

I wanted to retrieve some data from a table based on two columns see the below table structure
Update
i want the output data based on two condition
1. if the code value is having 'Web' or 'Offline'.
2. Memo column is having data same as Pre_memo column.
Output should be as shown below
So far i got the output by using same table two times but i wanted to get the output result by using the table only 1 time to avoid performance related issues as this table is having huge data.
select distinct OrderTable.Memo,
max(OrderTable.Memo_Date) as Date1,
max(ot.Pre_Memo_Date) as Date2
from OrderTable,
OrderTable ot
where OrderTable.code in ('Web')
and ot.code in ('Offline')
and OrderTable.Memo = ot.Pre_Memo
group by OrderTable.Memo
Can anyone help on this? With the use of OrderTable only once in the query and filter based on memo and pre_memo column as it's having same data?
You can use union all and do the conditional aggregation :
select Memo, max(case when code = 'Offline' then Date end) as Memo_date,
max(case when code = 'Web' then Date end) as Per_Memo_date
from (select Date, 'Web' as code, Pre_memo as Memo
from OrderTable o
where code = 'Web'
union all
select Date, 'Offline', Memo
from OrderTable o
where code = 'Offline'
) t
group by Memo;
"I wanted to retrieve some data from a table based on two columns see the below table structure"
Providing a sample is sufficient to illustrate the problem (and it is desirable to do so on SO) but it is not sufficient and thus not a replacement for defining the problem, which you have failed to do.
Absent such definition of the problem, we can only guess what you're trying to achieve. E.G.
from the subset of tuples that have 'Offline' for 'code' value, take the MAX() 'Date' value per appearing value of 'Memo'.
Match that (using some matching condition) to the subset of tuples that have 'Web' for 'code value and retain the 'Date' value from those as 'Memo_date' in the result set.
matching condition being that 'Memo' value of [a tuple in] the former is equal to 'Pre_memo' value in [the matching tuple in] the latter.
If all that is correct, then that explains why it is impossible to do this in SQL without having at least two references. You cannot avoid doing some kind of matching, and matching by definition takes two distinct things to match (even if the two distinct things are distinct subsets of one and the same thing). In fact it is almost certainly a fundamental design mistake for you to have those two distinct things in one single table, probably under the totally misguided belief that "having everything in one table makes things easier".
"So far i got the output by using same table two times but i wanted to get the output result by using the table only 1 time to avoid performance related issues as this table is having huge data"
From the way you have presented the question, I suspect that you were hoping for some means to exploit the fact that those 'Offline' tuples are "the next" after a 'Web' tuple, and that you could write the SQL in such a way that the engine could then derive a sort of "single pass" algorithm (which you probably assume would go faster).
It does not work like that. SQL tables have no inherent ordering and as a consequence there simply ain't no such thing as "the next" in a table.