Self-Referencing Table SQL Select last element from included elements - sql

I have tables:
create table Branches(
Id int primary key identity,
IdSection int not null,
IdMasterBranch int null,
[Name] varchar(100) not null,
[Description] varchar(300) null
)
create table Threads(
Id int primary key identity,
IdBranch int not null,
IdUserAuthor int not null,
[Name] varchar(100) not null,
IsPinned bit not null,
IsOpen bit not null,
HasPoll bit not null
)
create table Posts(
Id int primary key identity,
IdThread int not null,
IdUserAuthor int not null,
Body varchar(4000) not null,
IsEdited bit not null,
[Index] int not null,
Created datetime2 not null,
Updated datetime2 null
)
Branches is self referencing table, that contains another branches.
And i wanna write sql request to select all master branches (IdMasterBranch IS NULL) with last thread and last post.
Something like this:
select * from Branches branch
left join BranchModerators moderator on branch.Id = moderator.IdBranch
left join Threads thread on branch.Id = thread.IdBranch
left join (select * from (
select *,
ROW_NUMBER() over (
partition by IdThread
order by [Index] desc
) as RowNumber
from Posts
) groups
where groups.RowNumber = 1) lastPost on thread.Id = lastPost.IdThread
But i wanna take last thread and post with included inner branches too.
What is the best solution for it?

Related

SQLServer how to convert single row values in to multiple rows with each property as separat

I have a user defined type which is passed to my sql stored procedure:
CREATE TYPE [dbo].[LearningDelivery] AS TABLE(
[LearnAimRef] NVARCHAR(10) NOT NULL,
[AimType] INT NOT NULL,
[AimSeqNumber] INT NOT NULL,
);
i have a table with structure as below. I want to match join the type name from the above definition into the ElementName column of the FieldDefinitation table and insert separate insert statements. can anyone help me how to achieve this?
CREATE TABLE [dbo].[LearningAimData]
(
[Id] INT IDENTITY(1, 1) NOT NULL,
[LearnerId] INT NOT NULL,
[FieldId] INT NOT NULL,
[Data] VARCHAR(128) NOT NULL
)
I want to insert each type i.e LearnAimRef , AimType as individual row values in the LearningAimData.
I have a lookup table for [FieldId]
CREATE TABLE [dbo].[FieldDefinition]
(
[Id] INT IDENTITY(1, 1),
[FieldId] INT NOT NULL,
[Name] VARCHAR(50) NOT NULL,
[ElementName] VARCHAR(50) NOT NULL
)

What is wrong with this access query?

Running the below query returns 0 records, but I would expect it to return 3.
SELECT
ID,
DW2_TV_DimStation_Id,
DW2_OTT_DimStation_Id,
Name,
CoreTVCode,
CoreOTTCode,
StrataTVCode,
HouseHolds,
MaleSkew,
FemaleSkew,
AverageAge,
AverageIncome,
BroadReach,
Description,
Owner,
Notes,
timestamp,
CreatedOn,
ModifiedOn,
Retired,
1 AS Accepted
FROM
Planning_DimStation AS src
WHERE
src.[timestamp] = (
SELECT
MAX([timestamp])
FROM
Planning_DimStation AS src2
WHERE
src2.[ID] = src.[ID]
)
AND NOT EXISTS (
SELECT
1
FROM
DimStation AS tgt
WHERE
tgt.[ID] = src.[ID]
);
The part that breaks it is the NOT EXISTS statement. If I delete the NOT EXISTS it works fine.
Table 1: Planning_DimStation
Is an SQL table linked with 3 records in it. Source below.
Table 2: DimStation
Is an Access table (pic of source UI below) that is empty
Could this be a silent fail caused by type missmatch?
Table 1:
CREATE TABLE [Planning].[DimStation]
(
[ID] INT PRIMARY KEY,
[DW2_TV_DimStation_Id] INT NULL,
[DW2_OTT_DimStation_Id] INT NULL,
[Name] NVARCHAR(128) NOT NULL,
[CoreTVCode] CHAR(5) NULL,
[CoreOTTCode] CHAR(10) NULL,
[StrataTVCode] CHAR(10) NULL,
[HouseHolds] DECIMAL(5,2) NULL,
[MaleSkew] DECIMAL(5,2) NULL,
[FemaleSkew] DECIMAL(5,2) NULL,
[AverageAge] INT NULL,
[AverageIncome] DECIMAL(23,2) NULL,
[BroadReach] BIT NULL,
[Description] NVARCHAR(MAX) NULL,
[Owner] NVARCHAR(128) NULL,
[Notes] NVARCHAR(MAX) NULL,
[timestamp] timestamp NOT NULL,
[CreatedOn] DATETIME2(7) CONSTRAINT [df_Planning_DimStation_CreatedOn] DEFAULT (sysutcdatetime()) NOT NULL,
[ModifiedOn] DATETIME2(7) CONSTRAINT [df_Planning_DimStation_ModifiedOn] DEFAULT (sysutcdatetime()) NOT NULL,
[Retired] BIT CONSTRAINT [df_Planning_DimStation_Retired] DEFAULT (0) NOT NULL
)
GO
Table 2:
Joining on different data types tends to yield unexpected results.
To fix this, use casts.
A note is that Access doesn't allow nulls to be cast. So we need to work around that using Nz (same as ISNULL in T-SQL) and explicitly handling nulls.
AND NOT EXISTS (
SELECT
1
FROM
DimStation AS tgt
WHERE
CLng(IIF(tgt.[ID] IS NULL, 0, tgt.ID)) = src.[ID] AND NOT tgt.ID IS NULL
);

Ambiguous column name 'ProductNumber'

Can't figure out why my question 3 is getting the error mentioned above.
Below is my code
/* Question 1 */
CREATE TABLE CUSTOMERS
(
CustomerID INT PRIMARY KEY,
CustFirstName VARCHAR(50) NOT NULL,
CustLastName VARCHAR(50) NOT NULL,
CustStreetAddress VARCHAR(50) NOT NULL,
CustCity VARCHAR(50) NOT NULL,
CustState VARCHAR(26) NOT NULL,
CustZipCode INT NOT NULL,
CustAreaCode INT NOT NULL,
CustPhoneNumber VARCHAR (26) NOT NULL
);
CREATE TABLE EMPLOYEES
(
EmployeeID INT PRIMARY KEY,
EmpFirstName VARCHAR(50) NOT NULL,
EmpLastName VARCHAR(50) NOT NULL,
EmpCity VARCHAR (50) NOT NULL,
EmpState VARCHAR(26) NOT NULL,
EmpZipCode INT NOT NULL,
EmpAreaCode INT NOT NULL,
EmpPhoneNumber VARCHAR(26) NOT NULL,
EmpBirthDate DATE NOT NULL
);
CREATE TABLE ORDERS
(
OrderNumber INT PRIMARY KEY,
OrderDate DATE NOT NULL,
ShipDate DATE NOT NULL,
CustomerID INT NOT NULL,
EmployeeID INT NOT NULL,
FOREIGN KEY(EmployeeID) REFERENCES EMPLOYEES(EmployeeID),
FOREIGN KEY(CustomerID) REFERENCES CUSTOMERS(CustomerID)
);
CREATE TABLE CATEGORIES
(
CategoryID INT PRIMARY KEY,
CategoryDescription VARCHAR(255) NOT NULL
);
CREATE TABLE PRODUCTS
(
ProductNumber INT PRIMARY KEY,
ProductName VARCHAR(50) NOT NULL,
ProductDescription VARCHAR(255) NOT NULL,
RetailPrice INT NOT NULL,
QuantityOnHand INT NOT NULL,
CategoryID INT NOT NULL,
FOREIGN KEY(CategoryID) REFERENCES CATEGORIES (CategoryID)
);
CREATE TABLE ORDER_DETAILS
(
OrderNumber INT NOT NULL,
ProductNumber INT NOT NULL,
QuotedPrice INT NOT NULL,
QuantityOrdered INT NOT NULL,
PRIMARY KEY (OrderNumber, ProductNumber),
FOREIGN KEY (OrderNumber) REFERENCES ORDERS(OrderNumber),
FOREIGN KEY(ProductNumber) REFERENCES PRODUCTS(ProductNumber)
);
CREATE TABLE VENDORS
(
VendorID INT PRIMARY KEY,
VendName VARCHAR(100) NOT NULL,
VendStreetAddress VARCHAR(50) NOT NULL,
VendCity VARCHAR(50) NOT NULL,
VendState VARCHAR(26) NOT NULL,
VendFaxNumber VARCHAR(50) NOT NULL,
VendWebPage VARCHAR(100) NOT NULL,
VendEmailAddress VARCHAR(100) NOT NULL
);
CREATE TABLE PRODUCT_VENDORS
(
ProductNumber INT NOT NULL,
VendorID INT NOT NULL,
WholeSalePrice INT NOT NULL,
DaysToDeliver INT NOT NULL,
PRIMARY KEY(ProductNumber, VendorID),
FOREIGN KEY(ProductNumber) REFERENCES PRODUCTS(ProductNumber),
FOREIGN KEY(VendorID) REFERENCES Vendors(VendorID)
);
/* QUESTION 2 */
SELECT
OrderDate, CustFirstName, CustLastName
FROM
CUSTOMERS C, ORDERS O
WHERE
C.CustomerID = O.OrderNumber;
/* QUESTION 3 */
SELECT
ProductNumber, WholeSalePrice, VendName
FROM
PRODUCTS P, PRODUCT_VENDORS PV, VENDORS V
WHERE
P.PRODUCTNUMBER = PV.ProductNumber AND PV.VendorID = V.VendorID;
I got the error
Ambiguous column name 'ProductNumber'
Because there are two table have column name of ProductNumber in your query you need to tell DB engine which column you want to get.
Also, use JOIN instead of , comma CROSS JOIN, because Join is more clear than a comma on the relationship between the two tables
SELECT PV.ProductNumber, WholeSalePrice, VendName
FROM PRODUCTS P
JOIN PRODUCT_VENDORS PV ON P.PRODUCTNUMBER = PV.ProductNumber
JOIN VENDORS V ON PV.VendorID = V.VendorID;
Your query stipulates SELECT ProductNumber From two tables that both have ProductNumber. In the SELECT columns list, prefix ProductNumber with the table name from which you want to receive the data.
also, Have a look at your question 2. I don't think you really want to join customer id to order number, and you should use JOIN syntax intead of joining in the WHERE clause
Ambiguous error means that you are calling a certain field in which exist in both Table and the SQL has no idea where to get it. See, with your query, you're just literally calling the ProductNumber field in which the SQL has no idea where to get it since there are ProductNumber fields on both Tables, and you didn't specify any table.
so it is better when you have same column in multiple tables use table preface 1st then column like table1.col1,table2.col2
so in your case
SELECT p.ProductNumber, WholeSalePrice, v.VendName
FROM PRODUCTS P join
PRODUCT_VENDORS PV on P.PRODUCTNUMBER = PV.ProductNumber //
join VENDORS V on PV.VendorID = V.VendorID //use join instead your's

Can one table have two identity columns in SQL Server?

I am trying to make two columns auto increment but this column shows an error [user_id] as id + 0 PRIMARY KEY NOT NULL saying
Only UNIQUE or PRIMARY KEY constraints can be created on computed columns
What I am trying to do is, if id = 1, make user_id= 1 as well.
CREATE TABLE [dbo.TBL_TXN_USER]
(
[id] int NOT NULL IDENTITY(1,1),
[user_id] as id + 0 PRIMARY KEY NOT NULL ,
[username] varchar(150) NOT NULL,
[fullname] varchar(150) NOT NUll,
[pwd] varchar(50) NOT NUll,
[email] varchar(150) NOT NULL,
[mobile] varchar(150) NOT NULL,
[designation] varchar(150) NOT NULL,
[deleted] int NULL,
[created_date] datetime NULL,
[creator_user_id] int NULL,
[changed_date] datetime NULL,
[changer_user_id] int NULL,
[add_content] int NULL,
[edit_content] int NULL,
[delete_content] int NULL,
[manage_user] int NULL,
[view_log] int NULL,
)
What is wrong in [user_id]? How to solve it?
the error message is because you put the NOT NULL constraint on the computed column.
on sql server 2012 the complete error message is:
Only UNIQUE or PRIMARY KEY constraints can be created on computed
columns, while CHECK, FOREIGN KEY, and NOT NULL constraints require
that computed columns be persisted.
here is a working script (i changed the table name):
CREATE TABLE dbo.[TBL_TXN_USER]
(
[id] int NOT NULL IDENTITY(1,1),
[user_id] as id + 0 persisted not null primary key,
[username] varchar(150) NOT NULL,
[fullname] varchar(150) NOT NUll,
[pwd] varchar(50) NOT NUll,
[email] varchar(150) NOT NULL,
[mobile] varchar(150) NOT NULL,
[designation] varchar(150) NOT NULL,
[deleted] int NULL,
[created_date] datetime NULL,
[creator_user_id] int NULL,
[changed_date] datetime NULL,
[changer_user_id] int NULL,
[add_content] int NULL,
[edit_content] int NULL,
[delete_content] int NULL,
[manage_user] int NULL,
[view_log] int NULL,
);
GO
i have a couple of comments about that question .
- a calculated field with a fixed formula with static values as primary key instead of the id itself is a waste of resources: one of the 2 fields should not be there
- a field with the name of a system function (user_id) is something i would avoid at all costs.
- the question looks like an attempt to put in place a solution (the calculated field as id) for an hidden issue.
Sorry for my misunderstanding, So you want to add auto increments two column in one table. Actually that is not accept at SQL-server so I am going to give you another option below
CREATE TRIGGER [dbo].[insert_triger] ON [dbo].[TBL_TXN_USER]
FOR INSERT
AS
update TBL_TXN_USER set [user_id] = id
where id = (
select MAX(id)
from TBL_TXN_USER
)
column aliases work with select statement not create table, also for [user_id] you didn't provide any data type.
Use the following to create your table :
CREATE TABLE [dbo.TBL_TXN_USER](
[id] int NOT NULL IDENTITY(1,1),
[user_id] int PRIMARY KEY NOT NULL ,
....rest of code
To update [user_id] consider using a trigger.

Deleting duplicates in SQL Server [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
SQL - How can I remove duplicate rows?
I have a table that's structured like this:
create table MnA
(id int PRIMARY KEY IDENTITY not null,
symbol nvarchar(4) not null,
direction nvarchar(4) not null,
start_dt nvarchar(5) not null,
end_dt nvarchar(5) not null,
start_doy int not null,
end_doy int not null,
avg_price int not null,
min_price int not null,
max_price int not null,
avg_percent int not null,
min_percent int not null,
max_percent int not null,
history text not null,
percent_hit int not null,
aw_length int not null,
diff int not null,
date_change int not null)
I would like to delete rows that have similarities.
If the row has the same symbol, direction, start_doy and diff then I want to keep the one with the highest avg_percent.
How would I accomplish this?
DELETE target
FROM MnA target INNER JOIN MnA temp
ON (target.symbol = temp.symbol
AND target.direction = temp.symbol
AND target.start_doy = temp.start_doy
AND target.diff = temp.diff
AND target.id != temp.id
AND temp.avg_percent > target.avg_percent);
DEMO (sqlfiddle).