I want to generate a unique PrescriptionNo for each of the Prescription based on the shopid.
I have tried the following way
id PrescriptionNo Shopid Amount
1 PRES001 2 100
2 PRES002 2 200
3 PRES001 1 100
4 PRES003 2 200
select top 1 'PRES' + right('000' + CAST(ROW_NUMBER() over (order by id) + 1 AS VARCHAR(3)),3)
from prescription
where shopid = 2
order by id desc
Try this:
create table #tmp1 (id int, prescriptionno varchar(10), shopid int, amount int);
insert into #tmp1 values (1,'PRES001',2,100);
insert into #tmp1 values (2,'PRES002',2,200);
insert into #tmp1 values (3,'PRES001',1,100);
insert into #tmp1 values (4,'PRES003',2,200);
select 'PRES' + RIGHT(concat('000',ISNULL(max(right(prescriptionNo,3)),0)+1),3)
from #tmp1
where shopid = 3
=> Returns 'PRES0001'
select 'PRES' + RIGHT(concat('000',ISNULL(max(right(prescriptionNo,3)),0)+1),3)
from #tmp1
where shopid = 2
==> Returns 'PRES0004'
By using just max() allows you to use ISNULL(..,0).
Related
I have a table bawe_services. i want to fetch all data that match with given keys
like i have fields
id | Service_id |bawe_id
1 2 2
2 3 3
3 2 3
if i pass service =2 i need all record of service_id=2 if i pass service=1,2,3 than i want 0 rows because 1 service is not given by any bawe so. i got 0 rows.
I use this query
select * from aspnet_bawe_services where ser_id in(1,2,3)
Thanx in advance
The count of the parameters in the "in" statement must match the having equal number.
select bawe_id from [dbo].[aspnet_bawe_services]
where Service_id in (2)
group by bawe_id
having count(Service_id)=1;
bawe_id
-----------
2
3
select bawe_id from [dbo].[aspnet_bawe_services]
where Service_id in (2,3)
group by bawe_id
having count(Service_id)=2;
bawe_id
-----------
3
select bawe_id from [dbo].[aspnet_bawe_services]
where Service_id in (1,2,3)
group by bawe_id
having count(Service_id)=3;
bawe_id
-----------
(0 row(s) affected)
TRY THIS: It's really tedious but unique requirement and I think to accomplish this, we have to use function
1-Function returns distinct count of service_id
2-Function to split comma separated value and return in table format
--Function returns distinct count of service_id
CREATE FUNCTION [dbo].[getCount](#service_id varchar(500))
RETURNS INT
AS
BEGIN
DECLARE #count int
SELECT #count = COUNT(DISTINCT(t.service_id))
FROM tmptos t
INNER JOIN [dbo].[SplitValue](#service_id, ',') tt on t.service_id = tt.items
RETURN #count
END;
--Function to split comma separated value and return in table format
--Function copied from
--separate comma separated values and store in table in sql server
CREATE FUNCTION [dbo].[SplitValue](#String varchar(MAX), #Delimiter char(1))
RETURNS #temptable TABLE (items VARCHAR(MAX))
AS
BEGIN
DECLARE #idx int
DECLARE #slice varchar(8000)
SELECT #idx = 1
if len(#String)<1 or #String is null return
WHILE #idx!= 0
BEGIN
set #idx = charindex(#Delimiter,#String)
IF #idx!=0
set #slice = left(#String,#idx - 1)
else
set #slice = #String
IF(LEN(#slice)>0)
INSERT INTO #temptable(Items) values(#slice)
SET #String = right(#String,len(#String) - #idx)
IF LEN(#String) = 0 break
END
RETURN
END;
--Table with Sample Data
create table tmptos(id int, Service_id int, bawe_id int)
insert into tmptos values
(1, 2, 2),
(2, 3, 3),
(3, 2, 3)
declare #service_id varchar(50) = '2,3'
select *
from tmptos t
inner join [dbo].[SplitValue](#service_id, ',') tt on t.Service_id = tt.items
where [dbo].[getCount](#service_id) = (select count(distinct(items)) from [dbo].[SplitValue](#service_id, ','))
OUTPUT:
id Service_id bawe_id items
1 2 2 2
2 3 3 3
3 2 3 2
It's bit lengthy but works perfectly.
select * from aspnet_bawe_services
where Service_id in (1,2,3)
and
( select count(distinct Service_id) from aspnet_bawe_services where Service_id in (1,2,3) ) = 3
last number in query (in this case "3") is elements count, which you have in IN list.
You can get the service ids that you want using group by and having:
select service_id
from t
where bawe_id in (1, 2, 3)
group by service_id
having count(distinct bawe_id) = 3;
The "= 3" is the number of ids in the IN list.
You can then use in or join or exists to get the full records:
select t.*
from t
where t.service_id in (select service_id
from t
where bawe_id in (1, 2, 3)
group by service_id
having count(distinct bawe_id) = 3
);
I have the following table structure
| id | parentID | count1 |
2 -1 1
3 2 1
4 2 0
5 3 1
6 5 0
I increase count values from my source code, but i also need the increase in value to bubble up to each parent id row until the parent id is -1.
eg. If I were to increase count1 on row ID #6 by 1, row ID #5 would increase by 1, ID #3 would increase by 1, and ID #2 would increase by 1.
Rows also get deleted, and the opposite would need to happen, basically subtracting the row to be deleted' value from each parent.
Thanks in advance for your insight.
I'm using SQL Server 2008, and C# asp.net.
If you really want to just update counts, you could want to write stored procedure to do so:
create procedure usp_temp_update
(
#id int,
#value int = 1
)
as
begin
with cte as (
-- Take record
select t.id, t.parentid from temp as t where t.id = #id
union all
-- And all parents recursively
select t.id, t.parentid
from cte as c
inner join temp as t on t.id = c.parentid
)
update temp set
cnt = cnt + #value
where id in (select id from cte)
end
SQL FIDDLE EXAMPLE
So you could call it after you insert and delete rows. But if your count field are depends just on your table, I would suggest to make a triggers which will recalculate your values
You want to use a recursive CTE for this:
with cte as (
select id, id as parentid, 1 as level
from t
union all
select cte.id, t.parentid, cte.level + 1
from t join
cte
on t.id = cte.parentid
where cte.parentid <> -1
) --select parentid from cte where id = 6
update t
set count1 = count1 + 1
where id in (select parentid from cte where id = 6);
Here is the SQL Fiddle.
I have three tables Good Receive header ,Good Receive Details table and stock Table
TB_GoodsReceive_HDR - Header Table
ID SupplierID
1 1
TB_GoodsReceive_DTL - Details Table
ID GR_HDR_ID ItemID WarehouseID ExpiryDate Qty
1 1 1 1 4/4/2012 20
2 1 2 1 4/4/2012 30
TB_Stock - Stock Table
ID ItemID WarehouseID ExpiryDate StockType GR_HDR_ID Qty
1 1 1 4/4/2012 R 1 20
1 2 1 4/4/2012 R 1 30
I have received Item 1 – 20 Qty and Item2 - 30 Qty. Same I have it in my stock table.
There are lot of scenarios , But I need guidelines for this scenario
Now when user updates the TB_GoodsReceive_DTL as below: Updating the item only(ItemID 1 to ItemID 3)
ID GR_HDR_ID ItemID WarehouseID ExpiryDate Qty
1 1 **3** 1 4/4/2012 20
2 1 2 1 4/4/2012 30
My stock table values should be as follows:
ID ItemID WarehouseID ExpiryDate StockType GR_HDR_ID Qty
1 **3** 1 4/4/2012 R 1 20
1 2 1 4/4/2012 R 1 30
But my below stored procedure inserts the new row rather updating the row in the stock master.
Likewise user might update the warehouse or expiry date
The below procedure does the following:
Whenever the goods are received it will check the itemid, warehouse and expirydate in the stock table,if exists it will add the QTY else it will insert the new item in stock table.
The Problem is whenever the Good Receive table is updated(means when user updates ItemId or Expiry Date or Warehouse) how to update the stock table.
Please help me guys, its breaking my head...
Declare
#ItemID int,
#WareHouseID int,
#Qty int,
#StockType nvarchar(30),
#ExpiryDate datetime,
#IsExistsItem int,
#IsExistsWH int,
#IsExistsExpiryDate int,
#IsGR_HDR_ID int,
#GR_HDR_ID int
set #ItemID=1
set #WareHouseID=2
set #Qty=20
set #StockType='R'
set #GR_HDR_ID=2
set #ExpiryDate = '4/4/2012 12:00:00 AM'
set #IsExistsItem = (select count(ItemID) from TB_Stock_Details where
ItemID=#ItemID)
set #IsExistsWH = (select count(WareHouseID) from TB_Stock_Details where
WareHouseID=#WareHouseID)
set #IsExistsExpiryDate = (select count(ExpiryDate) from TB_Stock_Details where
ExpiryDate=#ExpiryDate)
if(#StockType='R')
begin
IF (#IsExistsItem>0) and (#IsExistsWH>0) and (#IsExistsExpiryDate>0)
BEGIN
UPDATE TB_Stock_Details
SET
Qty =Qty + #Qty
WHERE ItemID = #ItemID and GR_HDR_ID = #GR_HDR_ID
END
ELSE
begin
INSERT INTO TB_Stock_Details(ItemID,WareHouseID,Qty,StockType,ExpiryDate)
VALUES(#ItemID,#WareHouseID,#Qty,#StockType,#ExpiryDate)
end
end
First of all after the UPDATE you have two end statements, one is enough.
The reason why the quantity is not increased is because when you insert to the stock details table, you do not set the value for the GR_HDR_ID column. In your update command you set a filter on GR_HDR_ID, but the condition never will be satisfied because it has no value in your table.
edit:
For the scenario you described you need both the old and the new values as parameters, and based on these you can update the stock table too. Without these you cannot know what should be changed, you just get a bunch of new data.
A better alternative for this is to create an update trigger on TB_GoodsReceive_DTL table, in which you have access both the old a new values (inserted and deleted tables) and can update related records in the Stock table.
once there are new data insert to my DB my rcount will increase by 1, what am i trying to do is to display latest inserted record to users, but i cant get my expected result
rCount in my datebase
1
2
3
4
5
output
5
4
3
1
2
expected output
5
4
3
2
1
"SELECT *, ROW_NUMBER() OVER (ORDER BY rCount DESC) AS 'RowNumber'
FROM [MovieListTable]"
Instead of using the row number you should introduce a numeric primary key (i.e. Id) and make it an Identity column. Now you can just select the row that has the maximum Id value:
select top 1 * from MovieListTable order by Id desc
Or to get all rows:
select * from MovieListTable order by Id desc
I have successfully simulated an Oracle CONNECT BY statement in SQL Server 2008 by following these 2 previous answers here and here and adjusting to get the results I need. But how do I do this in LINQ?
Here is an example of what I am doing using a dummy database:
CREATE TABLE Employee(
EmployeeID INT IDENTITY(1,1) PRIMARY KEY,
Department INT NOT NULL,
EmployeeName VARCHAR(40) NOT NULL,
PeckingOrder INT NOT NULL,
HigherDepartment INT NULL)
INSERT INTO Employee (Department,EmployeeName,PeckingOrder,HigherDepartment)
VALUES (1,'Bart',1,NULL),(2,'Homer',1,1),(2,'Marge',2,NULL),
(3,'Lisa',1,2),(3,'Maggie',2,2),(3,'Santas Helper',3,1)
EmployeeID Department EmployeeName PeckingOrder HigherDepartment
1 1 Bart 1 NULL
2 2 Homer 1 1
3 2 Marge 2 NULL
4 3 Lisa 1 2
5 3 Maggie 2 2
6 3 Santas Helper 3 1
and this is the SQL used to return the heirachy:
WITH n(level, PeckingOrder, Department, EmployeeName, HigherDepartment) AS
(SELECT 1, PeckingOrder, Department, EmployeeName, HigherDepartment
FROM Test.dbo.Employee
WHERE Department = 3
UNION ALL
SELECT n.level + 1, nplus1.PeckingOrder, nplus1.Department, nplus1.EmployeeName, nplus1.HigherDepartment
FROM Test.dbo.Employee as nplus1
JOIN n ON n.HigherDepartment = nplus1.Department)
SELECT MAX(level) AS level, PeckingOrder, Department, EmployeeName, HigherDepartment
FROM n
GROUP BY PeckingOrder, Department, EmployeeName, HigherDepartment
ORDER BY MAX(level) DESC, PeckingOrder ASC
level PeckingOrder Department EmployeeName HigherDepartment
3 1 1 Bart NULL
2 1 2 Homer 1
2 2 2 Marge NULL
1 1 3 Lisa 2
1 2 3 Maggie 2
1 3 3 Santas Helper 1
You could use ExecuteQuery:
class YourRow
{
public int level {get; set;}
public int PeckingOrder {get; set;}
...
}
using (var db = new LinqDataContext())
{
var list = db.ExecuteQuery<YourRow>(
#"
WITH n(level, PeckingOrder, Department, EmployeeName, HigherDepartment) AS
(SELECT 1, PeckingOrder, Department, EmployeeName, HigherDepartment
...
";
}
Or perhaps better, create a view that contains the query, and use LINQ to read from the view.