Order a report builder report by the parameters entered - reporting-services

So I have an SSRS report with one parameter and got a request to order the report by the exact order that the parameter/order numbers entered. Is there any way to sort the report this way?
For example, the parameters/order numbers entered in order: 5, 10, 1, 3, 2
I need the report to come out in that exact order
Table:
Order Number
Customer
5
A
10
B
1
C
3
D
2
E
Below is the query too, but I don't think this is anything I could do in sql server anyway.
SELECT c.customer_name AS [Customer]
, oh.order_no AS [Pick Ticket Number]
FROM orders oh
INNER JOIN customer c ON oh.customer_id = c.customer_id
WHERE oh.order_no IN (#orderno)
GROUP BY c.customer_name, oh.order_no

If you are using a drop down list of order numbers for the user to choose from, then I don't you can do this easily as there is no way to know which order they were clicked in.
If the users are just typing into a multivalue parameter and pressing enter between each entry then you can do it like this...
Add new new parameter to your report (this can be hidden) call it something like 'pOrderSort` and set the Default Value expression to be
=JOIN(Parameters!orderno.Value, ",")
This will create a string, something like "5,10,1,3,2".
Now change your dataset query to this..
declare #Seq table(orderNum int, SortBy int IDENTITY(1,1))
INSERT INTO #Seq (orderNum)
SELECT value from string_split(#pOrderSort, ',')
SELECT c.customer_name AS [Customer]
, oh.order_no AS [Pick Ticket Number]
, s.SortBy
FROM orders oh
INNER JOIN customer c ON oh.customer_id = c.customer_id
INNER JOIN #Seq s ON oh.order_no = s.orderNum
GROUP BY c.customer_name, oh.order_no
ORDER BY s.SortBy
All we are doing here is splitting the passed in parameter into rows and assigning a sequence number in the SortBy column.
Now all we do is join to this table and order by the SortBy column. There is no need for the WHERE clause as we are joining only to the order number we need.
You can use the SortBy column in the report design to order the rows as required.

I had to do it without string_split() so below is the code to get around that, other than that I followed Alan's answer with creating a hidden parameter named #orderlist that is joined with the #orderno parameter
DECLARE #str varchar(max)
SET #str = #orderlist
DECLARE #separator varchar(max)
SET #separator = ','
DECLARE #Splited TABLE(id int IDENTITY(1,1), item decimal(19,0))
SET #str = REPLACE(#str, #separator, '''),(''')
SET #str = 'SELECT * FROM (VALUES(''' + #str + ''')) AS V(A)'
INSERT INTO #Splited
EXEC(#str)
SELECT c.customer_name AS [Customer]
, oh.order_no AS [Pick Ticket Number]
FROM oe_hdr oh
INNER JOIN customer c ON oh.customer_id = c.customer_id
INNER JOIN #Splited ot ON ot.item = oh.order_no
GROUP BY c.customer_name, op.pick_ticket_no, ot.id
ORDER BY ot.id ASC

Related

query make a count to 1 which does not satistfy the condition

i have a two table i want to know the number of person who are all assigned to project in each sector
CREATE TABLE first1( a int,projectname varchar(20));
INSERT INTO first1 VALUES
(1001,'crm'),
(1002,'iic'),
(1003,'abc'),
(1004,'sifty bank');
CREATE TABLE diff(b int,name varchar(20),p_id int );
INSERT INTO diff VALUES
(101,'priya',1001),
(102,'divya',1002),
(103,'sidhu',null),
(104,'shiva',null),
(105,'surya',1002);
Query:
select first1.projectname,count(*) from first1 left join diff on first1.a=diff.p_id group by
first1.projectname;
The output of this code is:
abc|1
crm|1
iic|2
sifty bank|1
The expected output is :
abc|0
crm|1
iic|2
sifty bank|0
The problem is count(*); it counts how many rows there are in each group - A project without any person assigned still counts as 1. Instead, you need to count() something from the left table, so null values are not taken into account:
select f.projectname, count(d.p_id) as cnt_diff
from first1 f
left join diff d on f.a = d.p_id
group by f.projectname;
Note that you can get the same result with a subquery:
select f.projectname,
(select count(*) from diff d where d.p_id = f.a) as cnt_diff
from first1 f

TOP N/% Chart in SSRS

I have a query which currently pulls back a list of sales by sales person throughout a particular financial year. This has been deployed in SSRS; I would now like to add a chart that graphs these sales, but I want to restrict the chart to the TOP N sales (by revenue) as there are over 10,000 sales people.
I would prefer not to have to change my query or result set.
Graph currently looks like this:
Current configuration of graph:
Current query looks like this:
SELECT
EMPD.emp_name,
SUM(ISNULL(CID.menu_item_sales_amount,0)) AS [Amount]
FROM ig_Business..Check_Item_Detail CID (NOLOCK) -- sum of sales by emp id
JOIN ig_Transaction..Transaction_Master TM (NOLOCK) on tm.transaction_data_id = cid.transaction_data_id AND tm.ent_id = 1 -- ent_id 1 equals not test data
JOIN ig_business..Check_Sales_Detail CSD (NOLOCK) ON CSD.transaction_data_id = CID.transaction_data_id -- tender period is stored here
JOIN ig_Dimension..Employee_Dimension EMPD (NOLOCK) ON CID.emp_dim_id = EMPD.emp_dim_id -- so we can get employee name
JOIN ig_Dimension..Menu_Item_Dimension MID (NOLOCK) on MID.menu_item_dim_id = CID.menu_item_dim_id and MID.ent_id = 1
JOIN ig_Dimension..Check_Type_Dimension CTD (NOLOCK) on CTD.check_type_dim_id = CSD.check_type_dim_id
/* Date Range Changed Below */
WHERE (
tm.updated_date_time BETWEEN #startdatecast AND #enddatecast
)
AND MID.report_category_id in (2,25,73,33,81,84,1,14)
AND CID.menu_item_status = 0
AND CTD.check_type_id in (1,5,7,10,9,12,13,14,15,16,17,20,21,22,23,24,25,27,28,29,30,31,33,34)
AND EMPD.emp_name NOT IN ('REUSE, REUSE','Trial3, Test','Trial, Trial','Test, Trial')
GROUP BY EMPD.emp_name
ORDER by [Amount] DESC,EMPD.emp_name
Add a filter to the category group, an example would be:
expression = [sum(Amount)]
operator = Top N
Value = 10

Mixed scenarios in MS Access

This is my table [Property]:
Loanno Balance amount PropertyType
1001045 308731.770000 1
1001045 2007700.740000 2
1001045 3087318905.770 3
1001045 308731.770000 4
1001046 306589.67 1
1001046 456321.23 1
1001046 6932542.89 1
1001047 582563.56 1
1001047 965421.34 2
1001048 567894.34 1
1001048 567894.34 2
I have to get the property type for a [Loanno] having highest balance amount.
If there is a tie in the highest balance amount and if the Property type for the loannumber is different then for that Loan number I have to populate property type as '8'.
So my final Output should look like this:
Loanno PropertyType
1001045 3
1001046 1
1001047 2
1001048 8
Edit
This is what I tried, but I am getting duplicate records.
SELECT DISTINCT
LT.LOANNO,
IIF(COUNTS.MAX_BALANCE > 1, 8,LT.PROPERTY_TYPE) AS PROPERTY_TYPE1
FROM
PROPERTY LT
INNER JOIN
(
SELECT
DISTINCT_ROWS.LOANNO,
COUNT(DISTINCT_ROWS.MaxBalance) AS MAX_BALANCE
FROM
(
SELECT DISTINCT
L.LOANNO,
MaxBalance
FROM
PROPERTY AS L
INNER JOIN
(
SELECT
LOANNO,
MAX(BALANCE_AMOUNT) AS MaxBalance
FROM PROPERTY
GROUP BY LOANNO
) AS SUB
ON (L.LOANNO=SUB.LOANNO)
AND (L.BALANCE_AMOUNT=SUB.MaxBalance)
) AS DISTINCT_ROWS
GROUP BY DISTINCT_ROWS.LOANNO
) AS COUNTS
ON LT.LOANNO=COUNTS.LOANNO
GROUP BY LT.LOANNO, IIF(COUNTS.MAX_BALANCE > 1, 8, LT.PROPERTY_TYPE)
Your query requirements are challenging for Access SQL. A custom VBA function would allow you to use a simpler SELECT statement, but brings issues which may be unacceptable for you:
A UDF (user-defined function) can only be used in a query run within an Access session ... not when you use other code (.Net, Java, PHP, VBScript, etc) to connect to the db and run your query.
UDFs can be slow.
If you can use a UDF, this query using the GetPropertyType function (see below) returns what you asked for. Note I used tblProperties as the table name because Property is a reserved word. Also I assumed Long for the data type of Loanno, Currency for Balance_amount, and Long for Property_Type.
SELECT
sub.Loanno,
GetPropertyType(sub.Loanno,sub.MaxBalance) AS PropertyType
FROM
(
SELECT
Loanno,
Max(Balance_amount) AS MaxBalance
FROM tblProperties
GROUP BY Loanno
) AS sub
ORDER BY sub.Loanno;
This is the function, which I tested with Access 2007.
Public Function GetPropertyType(ByVal pLoanno As Long, _
ByVal pBalance_amount As Currency) As Long
Const cstrQdf As String = "qryLoanPropertyTypesCount"
Dim db As DAO.database
Dim qdf As DAO.QueryDef
Dim lngReturn As Long
Set db = CurrentDb
Set qdf = db.QueryDefs(cstrQdf)
qdf.Parameters("which_Loanno") = pLoanno
qdf.Parameters("which_Balance_amount") = pBalance_amount
If qdf.OpenRecordset()(0) > 1 Then
lngReturn = 8
Else
lngReturn = DLookup("Property_Type", "tblProperties", _
"Loanno=" & pLoanno & " AND Balance_amount=" & _
pBalance_amount)
End If
Set qdf = Nothing
Set db = Nothing
GetPropertyType = lngReturn
End Function
The function uses this saved parameter query, qryLoanPropertyTypesCount:
PARAMETERS which_Loanno Long, which_Balance_amount Currency;
SELECT Count(*) AS num_PropertyTypes
FROM
(
SELECT DISTINCT
p.Loanno,
p.Balance_amount,
p.Property_Type
FROM tblProperties AS p
WHERE
p.Loanno = [which_Loanno]
AND p.Balance_amount = [which_Balance_amount]
) AS sub;
Here's how I built up the query:
Step 1: Create a query to find the maximum balance for each [Loanno] and save that query as [Loanno_MaxBalance]:
SELECT
Loanno,
MAX([Balance amount]) AS MaxBalance
FROM [Property]
GROUP BY Loanno
Step 2a: Create a query to count the number of rows that have the maximum balance, using our saved query above to keep things simple:
SELECT
[Property].Loanno,
[Property].[Balance amount],
COUNT(*) AS RowCount
FROM
[Property]
INNER JOIN
[Loanno_MaxBalance]
ON Loanno_MaxBalance.Loanno=[Property].Loanno
AND Loanno_MaxBalance.MaxBalance=[Property].[Balance amount]
GROUP BY [Property].Loanno, [Property].[Balance amount]
Step 2b: That doesn't look too scary, so let's incorporate the SQL from Step 1 as a subquery:
SELECT
[Property].Loanno,
[Property].[Balance amount],
COUNT(*) AS RowCount
FROM
[Property]
INNER JOIN
(
SELECT
Loanno,
MAX([Balance amount]) AS MaxBalance
FROM [Property]
GROUP BY Loanno
) AS Loanno_MaxBalance
ON Loanno_MaxBalance.Loanno=[Property].Loanno
AND Loanno_MaxBalance.MaxBalance=[Property].[Balance amount]
GROUP BY [Property].Loanno, [Property].[Balance amount]
So now this query stands on its own, and we don't need to keep [Loanno_MaxBalance] as a separate saved query in Access.
We'll save the above query as [Loanno_MaxBalance_Count].
Step 3a: Now to derive the [PropertyType] values using the [Property] table and the [Loanno_MaxBalance_Count] query:
SELECT DISTINCT
[Property].Loanno,
IIf(Loanno_MaxBalance_Count.RowCount>1, 8, [Property].PropertyType) AS PropertyType
FROM
[Property]
INNER JOIN
[Loanno_MaxBalance_Count]
ON [Property].Loanno=Loanno_MaxBalance_Count.Loanno
AND [Property].[Balance amount]=Loanno_MaxBalance_Count.[Balance amount]
Step 3b: Gee, that's not too bad at all. Let's "go for it" and replace the [Loanno_MaxBalance_Count] query reference with its SQL code (from Step 2b) as a subquery:
SELECT DISTINCT
[Property].Loanno,
IIf(Loanno_MaxBalance_Count.RowCount>1, 8, [Property].PropertyType) AS PropertyType
FROM
[Property]
INNER JOIN
(
SELECT
[Property].Loanno,
[Property].[Balance amount],
COUNT(*) AS RowCount
FROM
[Property]
INNER JOIN
(
SELECT
Loanno,
MAX([Balance amount]) AS MaxBalance
FROM [Property]
GROUP BY Loanno
) AS Loanno_MaxBalance
ON Loanno_MaxBalance.Loanno=[Property].Loanno
AND Loanno_MaxBalance.MaxBalance=[Property].[Balance amount]
GROUP BY [Property].Loanno, [Property].[Balance amount]
) AS Loanno_MaxBalance_Count
ON [Property].Loanno=Loanno_MaxBalance_Count.Loanno
AND [Property].[Balance amount]=Loanno_MaxBalance_Count.[Balance amount]
That's it! One self-contained query with no need for saved Access query dependencies.

Efficient sql server paging

Due to the first two comments I've removed all my own code and placed the example directly from 4 guys here.
I'm interested in how the 'select #first_id' should be coded. The example shows the rows being pulled using joins and I would expect that the first_id wouldn't be a valid place to start because it doesn't use the same join syntax.
CREATE PROCEDURE [dbo].[usp_PageResults_NAI]
(
#startRowIndex int,
#maximumRows int
)
AS
DECLARE #first_id int, #startRow int
-- A check can be added to make sure #startRowIndex isn't > count(1)
-- from employees before doing any actual work unless it is guaranteed
-- the caller won't do that
-- Get the first employeeID for our page of records
SET ROWCOUNT #startRowIndex
SELECT #first_id = employeeID FROM employees ORDER BY employeeid
-- Now, set the row count to MaximumRows and get
-- all records >= #first_id
SET ROWCOUNT #maximumRows
SELECT e.*, d.name as DepartmentName
FROM employees e
INNER JOIN Departments D ON
e.DepartmentID = d.DepartmentID
WHERE employeeid >= #first_id
ORDER BY e.EmployeeID
SET ROWCOUNT 0
GO
You can to efficient paging using ROW_NUMBER()
DECLARE #skipRows Int = 10 --Change to input parameter to sp
DECLARE #takeRows Int = 20 --Change to input parameter to sp
SELECT *
FROM (
SELECT
ROW_NUMBER() OVER (ORDER BY a.DateCreated) As RowNumber,
a.PKID,
a.AlertUrl,
a.AlertDescription,
a.Users_PKID_creator,
dbo.Users_GetFullName(a.Users_PKID_creator) as Users_FullName,
a.Dealers_PKID,
d.Dealer,
dbo.convertDateFromUTC(a.DateCreated, #dealers_pkid) as DateCreated,
dbo.convertDateFromUTC(a.DateCreated, #dealers_pkid) as ComparisonDate,
dbo.convertDateFromUTC(a.DateModified, #dealers_pkid) as DateModified,
a.Active,
a.Contacts_PKID,
dbo.Contacts_GetFullName(a.Contacts_PKID) as Contacts_FullName
from Alerts a
join Dealers d on d.PKID = a.Dealers_PKID
where a.DateCreated between dbo.convertDateToUTC(#datetimeDateStart, #dealers_pkid) and dbo.convertDateToUTC(#datetimeDateEnd, #dealers_pkid)
and a.Active = #bitActive
and a.PKID >= #first_id
) AS [t1]
WHERE [t1].RowNumber BETWEEN #skipRows + 1 AND #skipRows + #takeRows

MySQL - UPDATE query based on SELECT Query

I need to check (from the same table) if there is an association between two events based on date-time.
One set of data will contain the ending date-time of certain events and the other set of data will contain the starting date-time for other events.
If the first event completes before the second event then I would like to link them up.
What I have so far is:
SELECT name as name_A, date-time as end_DTS, id as id_A
FROM tableA WHERE criteria = 1
SELECT name as name_B, date-time as start_DTS, id as id_B
FROM tableA WHERE criteria = 2
Then I join them:
SELECT name_A, name_B, id_A, id_B,
if(start_DTS > end_DTS,'VALID','') as validation_check
FROM tableA
LEFT JOIN tableB ON name_A = name_B
Can I then, based on my validation_check field, run a UPDATE query with the SELECT nested?
You can actually do this one of two ways:
MySQL update join syntax:
UPDATE tableA a
INNER JOIN tableB b ON a.name_a = b.name_b
SET validation_check = if(start_dts > end_dts, 'VALID', '')
-- where clause can go here
ANSI SQL syntax:
UPDATE tableA SET validation_check =
(SELECT if(start_DTS > end_DTS, 'VALID', '') AS validation_check
FROM tableA
INNER JOIN tableB ON name_A = name_B
WHERE id_A = tableA.id_A)
Pick whichever one seems most natural to you.
UPDATE
`table1` AS `dest`,
(
SELECT
*
FROM
`table2`
WHERE
`id` = x
) AS `src`
SET
`dest`.`col1` = `src`.`col1`
WHERE
`dest`.`id` = x
;
Hope this works for you.
Easy in MySQL:
UPDATE users AS U1, users AS U2
SET U1.name_one = U2.name_colX
WHERE U2.user_id = U1.user_id
If somebody is seeking to update data from one database to another no matter which table they are targeting, there must be some criteria to do it.
This one is better and clean for all levels:
UPDATE dbname1.content targetTable
LEFT JOIN dbname2.someothertable sourceTable ON
targetTable.compare_field= sourceTable.compare_field
SET
targetTable.col1 = sourceTable.cola,
targetTable.col2 = sourceTable.colb,
targetTable.col3 = sourceTable.colc,
targetTable.col4 = sourceTable.cold
Traaa! It works great!
With the above understanding, you can modify the set fields and "on" criteria to do your work. You can also perform the checks, then pull the data into the temp table(s) and then run the update using the above syntax replacing your table and column names.
Hope it works, if not let me know. I will write an exact query for you.
UPDATE
receipt_invoices dest,
(
SELECT
`receipt_id`,
CAST((net * 100) / 112 AS DECIMAL (11, 2)) witoutvat
FROM
receipt
WHERE CAST((net * 100) / 112 AS DECIMAL (11, 2)) != total
AND vat_percentage = 12
) src
SET
dest.price = src.witoutvat,
dest.amount = src.witoutvat
WHERE col_tobefixed = 1
AND dest.`receipt_id` = src.receipt_id ;
Hope this will help you in a case where you have to match and update between two tables.
I found this question in looking for my own solution to a very complex join. This is an alternative solution, to a more complex version of the problem, which I thought might be useful.
I needed to populate the product_id field in the activities table, where activities are numbered in a unit, and units are numbered in a level (identified using a string ??N), such that one can identify activities using an SKU ie L1U1A1. Those SKUs are then stored in a different table.
I identified the following to get a list of activity_id vs product_id:-
SELECT a.activity_id, w.product_id
FROM activities a
JOIN units USING(unit_id)
JOIN product_types USING(product_type_id)
JOIN web_products w
ON sku=CONCAT('L',SUBSTR(product_type_code,3), 'U',unit_index, 'A',activity_index)
I found that that was too complex to incorporate into a SELECT within mysql, so I created a temporary table, and joined that with the update statement:-
CREATE TEMPORARY TABLE activity_product_ids AS (<the above select statement>);
UPDATE activities a
JOIN activity_product_ids b
ON a.activity_id=b.activity_id
SET a.product_id=b.product_id;
I hope someone finds this useful
UPDATE [table_name] AS T1,
(SELECT [column_name]
FROM [table_name]
WHERE [column_name] = [value]) AS T2
SET T1.[column_name]=T2.[column_name] + 1
WHERE T1.[column_name] = [value];
You can update values from another table using inner join like this
UPDATE [table1_name] AS t1 INNER JOIN [table2_name] AS t2 ON t1.column1_name] = t2.[column1_name] SET t1.[column2_name] = t2.column2_name];
Follow here to know how to use this query http://www.voidtricks.com/mysql-inner-join-update/
or you can use select as subquery to do this
UPDATE [table_name] SET [column_name] = (SELECT [column_name] FROM [table_name] WHERE [column_name] = [value]) WHERE [column_name] = [value];
query explained in details here http://www.voidtricks.com/mysql-update-from-select/
You can use:
UPDATE Station AS st1, StationOld AS st2
SET st1.already_used = 1
WHERE st1.code = st2.code
For same table,
UPDATE PHA_BILL_SEGMENT AS PHA,
(SELECT BILL_ID, COUNT(REGISTRATION_NUMBER) AS REG
FROM PHA_BILL_SEGMENT
GROUP BY REGISTRATION_NUMBER, BILL_DATE, BILL_AMOUNT
HAVING REG > 1) T
SET PHA.BILL_DATE = PHA.BILL_DATE + 2
WHERE PHA.BILL_ID = T.BILL_ID;
I had an issue with duplicate entries in one table itself. Below is the approaches were working for me. It has also been advocated by #sibaz.
Finally I solved it using the below queries:
The select query is saved in a temp table
IF OBJECT_ID(N'tempdb..#New_format_donor_temp', N'U') IS NOT NULL
DROP TABLE #New_format_donor_temp;
select *
into #New_format_donor_temp
from DONOR_EMPLOYMENTS
where DONOR_ID IN (
1, 2
)
-- Test New_format_donor_temp
-- SELECT *
-- FROM #New_format_donor_temp;
The temp table is joined in the update query.
UPDATE de
SET STATUS_CD=de_new.STATUS_CD, STATUS_REASON_CD=de_new.STATUS_REASON_CD, TYPE_CD=de_new.TYPE_CD
FROM DONOR_EMPLOYMENTS AS de
INNER JOIN #New_format_donor_temp AS de_new ON de_new.EMP_NO = de.EMP_NO
WHERE
de.DONOR_ID IN (
3, 4
)
I not very experienced with SQL please advise any better approach you know.
Above queries are for MySql server.
if you are updating from a complex query. The best thing is create temporary table from the query, then use the temporary table to update as one query.
DROP TABLE IF EXISTS cash_sales_sums;
CREATE TEMPORARY TABLE cash_sales_sums as
SELECT tbl_cash_sales_documents.batch_key, COUNT(DISTINCT tbl_cash_sales_documents.cash_sale_number) no_of_docs,
SUM(tbl_cash_sales_documents.paid_amount) paid_amount, SUM(A.amount - tbl_cash_sales_documents.bonus_amount - tbl_cash_sales_documents.discount_given) amount,
SUM(A.recs) no_of_entries FROM
tbl_cash_sales_documents
RIGHT JOIN(
SELECT
SUM(
tbl_cash_sales_transactions.amount
)amount,
tbl_cash_sales_transactions.cash_sale_document_id,
COUNT(transaction_id)recs
FROM
tbl_cash_sales_transactions
GROUP BY
tbl_cash_sales_transactions.cash_sale_document_id
)A ON A.cash_sale_document_id = tbl_cash_sales_documents.cash_sale_id
GROUP BY
tbl_cash_sales_documents.batch_key
ORDER BY batch_key;
UPDATE tbl_cash_sales_batches SET control_totals = (SELECT amount FROM cash_sales_sums WHERE cash_sales_sums.batch_key = tbl_cash_sales_batches.batch_key LIMIT 1),
expected_number_of_documents = (SELECT no_of_docs FROM cash_sales_sums WHERE cash_sales_sums.batch_key = tbl_cash_sales_batches.batch_key),
computer_number_of_documents = expected_number_of_documents, computer_total_amount = control_totals
WHERE batch_key IN (SELECT batch_key FROM cash_sales_sums);
INSERT INTO all_table
SELECT Orders.OrderID,
Orders.CustomerID,
Orders.Amount,
Orders.ProductID,
Orders.Date,
Customer.CustomerName,
Customer.Address
FROM Orders
JOIN Customer ON Orders.CustomerID=Customer.CustomerID
WHERE Orders.OrderID not in (SELECT OrderID FROM all_table)