How to create Invoice - sql-server

SELECT
dbo.PaymentMaster.Code,
dbo.PaymentMaster.OrderNo,
dbo.PaymentMaster.CustIssueNo,
dbo.PaymentMaster.Amount,
dbo.CustomerMaster.CustName,
dbo.OrderRequestMaster.ORequestQty,
InvoiceMaster.SGST,
InvoiceMaster.CGST,
InvoiceMaster.SGST,
InvoiceMaster.SubTotal,
InvoiceMaster.TotalAmount
FROM
dbo.CustomerIssueMaster,
dbo.PaymentMaster,
dbo.CustomerMaster,
dbo.OrderMaster,
dbo.OrderRequestMaster,
InvoiceMaster
WHERE (dbo.PaymentMaster.CustIssueNo = dbo.CustomerIssueMaster.CustIssueNo
OR OrderMaster.OrderNo = PaymentMaster.OrderNo)
AND OrderRequestMaster.ORequestNo = OrderMaster.ORequestNo
I want to create invoice where all conditions should be match but I didn't get any row when there is one row which should be given as result.
I got this result from payment master. and I want customer info, order request info , order info and payment info in invoice master with invoice master field i.e Code, InvoiceNo, CustNo, InvoiceDate, SubTotal, CGST, SGST, TotalAmount.
Code PaymentNo OrderNo CustIssueNo PaymentMode PaymentStatus Amount PaymentDate InvoiceNo InvoiceDate
4 KCS[P][00004] NULL KCS[CI][00001] Cash Paid 500 14:28.3 NULL NULL
5 KCS[P][00005] KCS[O][00001] NULL Cash Paid 2000 22:33.9 NULL NULL
6 KCS[P][00006] KCS[O][00002] NULL Cash Paid 2000 40:38.1 NULL NULL
I got this results

Without any data we are going to be very hard pressed to help. You say one row should meet criteria, but it is very hard to see how only one record would be returned unless your tables have only one record!
I note from your query that you want CustName, without including CustomerMaster in your WHERE clause - this will lead to trouble!
Please use the following code in a query window and add any missing fields that are important. Then create some INSERT lines to populate. Re-post this so that we can help you with a query that does what you want:
declare #CustomerIssueMaster table
(
CustIssueNo int
)
declare #PaymentMaster table
(
Code int,
PaymentNo varchar(50),
OrderNo varchar(50),
CustIssueNo varchar(50),
PaymentMode varchar(50),
PaymentStatus varchar(50),
Amount decimal (18,2),
PaymentDate datetime,
InvoiceNo int,
InvoiceDate datetime
)
declare #CustomerMaster table
(
CustName varchar(50)
)
declare #OrderRequestMaster table
(
ORequestQty int,
ORequestNo int
)
declare #InvoiceMaster table
(
SGST decimal(18,2),
CGST decimal(18,2),
SubTotal decimal(18,2),
TotalAmount decimal(18,2)
)
declare #OrderMaster table
(
OrderNo int
)
INSERT INTO #PaymentMaster VALUES(4, 'KCS[P][00004]', NULL, 'KCS[CI][00001]','Cash','Paid',500,'2014-03-28', NULL, NULL)
INSERT INTO #PaymentMaster VALUES(5, 'KCS[P][00005]', 'KCS[O][00001]', NULL, 'Cash','Paid',2000,'2014-03-28', NULL, NULL)
INSERT INTO #PaymentMaster VALUES(6, 'KCS[P][00006]', 'KCS[O][00002]', NULL, 'Cash','Paid',2000,'2014-03-28', NULL, NULL)
SELECT * FROM #PaymentMaster
EDIT
Please note I have amended the structure of #PaymentMaster and given three INSERTs to mimic the data you show from SELECT * FROM PaymentMaster, with one exception: I do not understand what format your PaymentDate is supposed to be. The first two looked like times, but the third cannot be. I just stuck in a dummy date instead.
Now will you please do the same for the other tables? I have shown you the format you need to use.

Related

Between clause not giving desired results in query

I need to return results from a mssql stored proc on the basis of datetime2. There's a employee table with punch in and punch out time. I need to return results all the data from an employee on the basis of start time and end time. My query is some what like
Select *
from employee
where empid ='123'
and punchin between 'starttime' and 'endtime'
and punchout between 'starttime' and 'endtime'
this query is not returning expected results. Am I doing anything wrong here, also in between punch in or punch out column one can be empty, in that case result will be returned on the basis of one column.
Based on assumption:
Table Structure:
CREATE TABLE employee (
empid VARCHAR(20) not null,
punchin datetime2(7),
punchout datetime2(7)
)
Sample data:
INSERT INTO employee VALUES
('1', null, '2021-03-28 10:50:00'),
('2', '2021-03-28 05:00:00', '2021-03-28 9:00:00'),
('3', '2021-02-28 05:00:00', null)
Procedure:
CREATE PROCEDURE getData
#empid VARCHAR(20),
#startTime datetime2(7),
#endTime datetime2(7)
AS
BEGIN
SELECT *
FROM employee
WHERE empid = #empid
AND (punchin IS NULL OR (punchin IS NOT NULL AND punchin >= #startTime))
AND (punchout IS NULL OR (punchout IS NOT NULL AND punchout <= #endTime))
END
Usage:
EXEC getData '1', '2021-03-27 10:50:00', '2021-03-27 10:50:00'
See, if it works.
Note: Without proper structure or data, it is hard to do things based on assumption.

SQL Query to Append Past Order with Most Recent Order

I have an order table that has both past membership data and current data. I want to view this data in single row. I have a temp table for past data, but not exactly sure how to write this query to get current data in the same row. I know it has something to do with the MAX(order no). Here is the query to get the past membership data in a temp table
set transaction isolation level read uncommitted
declare
#ship_master_customer_id varchar (10), #cycle_begin_date datetime, #cycle_end_date datetime, #OrderNo varchar(10), #Description Char(100)
create table #t1(ShipMasterCustomerID varchar(10), OrderNo varchar (10), cycle_begin_date datetime, cycle_end_date datetime, Description Char(100))
Insert into #t1
Select SHIP_MASTER_CUSTOMER_ID, ORDER_NO, CYCLE_BEGIN_DATE,CYCLE_END_DATE, DESCRIPTION FROM [ORDER_DETAIL]
where SHIP_MASTER_CUSTOMER_ID = '11115555' and
CYCLE_END_DATE = '2/29/2016'
Select * from #t1
Drop table #t1
Here is my script.
declare
#ship_master_customer_id varchar (10), #cycle_begin_date datetime, #cycle_end_date datetime, #OrderNo varchar(10), #Description Char(100)
create table #t2(ShipMasterCustomerID varchar(10), OrderNo varchar (10), cycle_begin_date datetime, cycle_end_date datetime, Description Char(100))
Insert into #t2 (shipmastercustomerid, orderno, cycle_begin_date, cycle_end_date, DESCRIPTION)
VALUES (1111555,9004731815, 2015/01/01, 2015/31/12,'Annual Mem'),
(1111555, 9005148308, 2016/01/01, 2016/31/12,'Annual Mem'),
(1111222, 9005027152, 2015/01/03, 2016/29/02,'Annual Mem'),
(1111222, 9005440369, 2016/01/03, 2017/31/03,'Annual Mem'),
(2223333, 9005027152, 2014/01/01, 2016/31/12,'Annual Mem'),
(2223333, 9005442116, 2016/01/01, 2017/31/12,'Annual Mem')
Select * from #t2
Drop table #t2
Sample Data
You don't need a temp table. You can query the same table twice, giving it an alias and then use the alias to prefix your column names. Since you didn't give us a complete schema or a fiddle I'm simulating your database with a temp table but the essence is here. There are considerations that you didn't mention, though. Are you guaranteed that every customer will have both a historical AND a current record? If not, they will not appear in the query below because of the INNER JOIN. You could change it to an OUTER join but when customers don't have a new record you will see NULL values in those columns. My point is that here be dragons... this is by no means a complete or bulletproof solution, only a nudge in the right direction.
DECLARE #ORDER_DETAIL AS TABLE(
ShipMasterCustomerId varchar(20),
OrderNo varchar(20),
cycle_begin_date date,
cycle_end_date date,
Description varchar(100)
)
INSERT #ORDER_DETAIL SELECT '11115555', '9005337015', '02/26/15', '2/29/16', 'Membership 26-Feb-2015 to 29-Feb-2016'
INSERT #ORDER_DETAIL SELECT '11115555', '9005743023', '02/28/17', '2/28/17', 'Membership 01-Mar-2016 to 28-Feb-2017'
SELECT
hist.ShipMasterCustomerId,
hist.OrderNo,
hist.cycle_begin_date,
hist.CYCLE_END_DATE,
hist.[Description],
curr.ShipMasterCustomerId,
curr.OrderNo,
curr.cycle_begin_date,
curr.CYCLE_END_DATE,
curr.[Description]
FROM
#ORDER_DETAIL AS hist
INNER JOIN #ORDER_DETAIL AS curr ON (
(curr.ShipMasterCustomerId = hist.ShipMasterCustomerId) AND (curr.cycle_end_date =
(SELECT MAX(cycle_end_date) FROM #ORDER_DETAIL WHERE ShipMasterCustomerId = hist.ShipMasterCustomerId))
)
WHERE
(hist.ShipMasterCustomerId = '11115555')
AND
(hist.cycle_end_date = '2/29/2016')

COUNT without GROUP BY clause issue

I'm probably missing something simple here. I have this first table:
CREATE TABLE [Orgnzs] (
[id] INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
[nm] NVARCHAR(256)
);
and then also several tables that are all created as such (all having the same structure):
-- WLog_* tables are all created as such
CREATE TABLE [WLog_1] (
[id] BIGINT NOT NULL IDENTITY(1,1) PRIMARY KEY,
[huid] UNIQUEIDENTIFIER,
[dtin] BIGINT,
[dtout] BIGINT,
[cnm] NVARCHAR(15),
[batt] TINYINT,
[pwrop] TINYINT,
[pst] INT,
[flgs] INT,
[ppocs] NVARCHAR(1024),
[ppocu] NVARCHAR(1024),
[por] NVARCHAR(1024)
);
and a similar set of tables, without last 3 columns of the table above:
-- ULog_* tables are all created as such
CREATE TABLE [ULog_1] (
[id] BIGINT NOT NULL IDENTITY(1,1) PRIMARY KEY,
[huid] UNIQUEIDENTIFIER,
[dtin] BIGINT,
[dtout] BIGINT,
[cnm] NVARCHAR(15),
[batt] TINYINT,
[pwrop] TINYINT,
[pst] INT,
[flgs] INT
);
My goal is to select records from arbitrary set of WLog_* and ULog_* tables, and limit it by manageable number of elements (for page layout) for which I also need to know the total count of records found.
So I do selection as such:
SELECT b.[id] AS evtID,
b.[huid] as huid,
b.[dtin] as dtin,
b.[dtout] as dtout,
b.[cnm] as cnm,
b.[batt] as batt,
b.[pwrop] as pwrop,
b.[pst] as pst,
b.[flgs] as flgs,
b.[ppocs] as ppocs,
b.[ppocu] as ppocu,
b.[por] as por,
b.[orgID] as orgID,
b.[wLg] as wLg,
orgz.[nm] as orgNm
, COUNT_BIG(*) as allRecordsFound
FROM (
-- next also specify the column(s) to sort by
SELECT *, ROW_NUMBER() OVER (ORDER BY [dtin], [cnm] ASC) AS rw FROM (
SELECT *, 1 AS orgID, 1 AS wLg
FROM [WLog_1]
UNION ALL
SELECT *, 2 AS orgID, 1 AS wLg
FROM [WLog_2]
UNION ALL
SELECT *, NULL AS [ppocs], NULL AS [ppocu], NULL AS [por], 1 AS orgID, 0 AS wLg
FROM [ULog_1]
) a
WHERE [pst]&1=1 OR [pst]=67
) b
LEFT JOIN [Orgnzs] AS orgz ON orgID=orgz.[id]
WHERE rw >= 2 AND rw <= 4 -- restrict for a page only
which unfortunately fails on the COUNT_BIG(*) as allRecordsFound line with the following error:
Column 'b.id' is invalid in the select list because it is not
contained in either an aggregate function or the GROUP BY clause.
I haven't used SQL Server for a while, can someone suggest what am I missing here?
PS. For a test purpose I made a Fiddle to try it out.
Use this instead:
count(*) over() as allRecordsFound
You can mix window aggregation function in select statement whithout grouping.

Insert from single table into multiple tables, invalid column name error

I am trying to do the following but getting an "Invalid Column Name {column}" error. Can someone please help me see the error of my ways? We recently split a transaction table into 2 tables, one containing the often updated report column names and the other containing the unchanging transactions. This leave me trying to change what was a simple insert into 1 table to a complex insert into 2 tables with unique columns. I attempted to do that like so:
INSERT INTO dbo.ReportColumns
(
FullName
,Type
,Classification
)
OUTPUT INSERTED.Date, INSERTED.Amount, INSERTED.Id INTO dbo.Transactions
SELECT
[Date]
,Amount
,FullName
,Type
,Classification
FROM {multiple tables}
The "INSERTED.Date, INSERTED.Amount" are the source of the errors, with or without the "INSERTED." in front.
-----------------UPDATE------------------
Aaron was correct and it was impossible to manage with an insert but I was able to vastly improve the functionality of the insert and add some other business rules with the Merge functionality. My final solution resembles the following:
DECLARE #TransactionsTemp TABLE
(
[Date] DATE NOT NULL,
Amount MONEY NOT NULL,
ReportColumnsId INT NOT NULL
)
MERGE INTO dbo.ReportColumns AS Trgt
USING ( SELECT
{FK}
,[Date]
,Amount
,FullName
,Type
,Classification
FROM {multiple tables}) AS Src
ON Src.{FK} = Trgt.{FK}
WHEN MATCHED THEN
UPDATE SET
Trgt.FullName = Src.FullName,
Trgt.Type= Src.Type,
Trgt.Classification = Src.Classification
WHEN NOT MATCHED BY TARGET THEN
INSERT
(
FullName,
Type,
Classification
)
VALUES
(
Src.FullName,
Src.Type,
Src.Classification
)
OUTPUT Src.[Date], Src.Amount, INSERTED.Id INTO #TransactionsTemp;
MERGE INTO dbo.FinancialReport AS Trgt
USING (SELECT
[Date] ,
Amount ,
ReportColumnsId
FROM #TransactionsTemp) AS Src
ON Src.[Date] = Trgt.[Date] AND Src.ReportColumnsId = Trgt.ReportColumnsId
WHEN NOT MATCHED BY TARGET And Src.Amount <> 0 THEN
INSERT
(
[Date],
Amount,
ReportColumnsId
)
VALUES
(
Src.[Date],
Src.Amount,
Src.ReportColumnsId
)
WHEN MATCHED And Src.Amount <> 0 THEN
UPDATE SET Trgt.Amount = Src.Amount
WHEN MATCHED And Src.Amount = 0 THEN
DELETE;
Hope that helps someone else in the future. :)
Output clause will return values you are inserting into a table, you need multiple inserts, you can try something like following
declare #staging table (datecolumn date, amount decimal(18,2),
fullname varchar(50), type varchar(10),
Classification varchar(255));
INSERT INTO #staging
SELECT
[Date]
,Amount
,FullName
,Type
,Classification
FROM {multiple tables}
Declare #temp table (id int, fullname varchar(50), type varchar(10));
INSERT INTO dbo.ReportColumns
(
FullName
,Type
,Classification
)
OUTPUT INSERTED.id, INSERTED.fullname, INSERTED.type INTO #temp
SELECT
FullName
,Type
,Classification
FROM #stage
INSERT into dbo.transacrions (id, date, amount)
select t.id, s.datecolumn, s.amount from #temp t
inner join #stage s on t.fullname = s.fullname and t.type = s.type
I am fairly certain you will need to have two inserts (or create a view and use an instead of insert trigger). You can only use the OUTPUT clause to send variables or actual inserted values ti another table. You can't use it to split up a select into two destination tables during an insert.
If you provide more information (like how the table has been split up and how the rows are related) we can probably provide a more specific answer.

sql server data insertion, first row closing balance should be next row opening balance

I am facing the problem while inserting data this way.
How to insert data this way using stored procedure.
INSERT INTO [dbo].tbl_Transaction
(
[FK_GameID] ,
[SpotID] ,
TransactionReason ,
TransactionType ,
TransactionAmount
--PrevAmountBalance,
-- CurrentBalance
)
SELECT tblTransaction.Row.value('#FK_GameID','BIGINT'),
tblTransaction.Row.value('#SpotID','SMALLINT'),
tblTransaction.Row.value('#TransactionReason','SMALLINT'),
tblTransaction.Row.value('#TransactionType','Varchar(50)'),
tblTransaction.Row.value('#TransactionAmount','MONEY')
--#OpeningBalance,
-- (#OpeningBalance-tblTransaction.Row.value('#TransactionAmount','MONEY'))
FROM #TransactionTable.nodes('/row') AS tblTransaction(Row)
create table #balances(
id int not null identity(1,1),
opening_balance int,
closing_balance int,
t_type varchar(50))
to start the table (if you don't have this you will have to deal with NULLs)
insert into #balances values (100 , 100 , 'start')
query:
insert into #balances values(
(select top 1 closing_balance from #balances order by id desc),
300, --new value
'credit')

Resources