SQL Server : how to set a column to a random value? - sql

I'm using SQL Server, I'm not experienced in T-SQL, but I want to generate random value including letters and numbers for one column for my project:
CREATE TABLE [dbo].[Orders]
(
[Id] INT NOT NULL,
[UserId] INT NOT NULL,
[MedicineId] INT NOT NULL,
[CourierId] INT NULL,
[ReadyForDelivery] BIT NOT NULL,
[OrderNumber] NVARCHAR(11) NOT NULL,
CONSTRAINT [PK_Orders] PRIMARY KEY CLUSTERED ([Id] ASC)
);
Id is my primary key also I want to put a random number and letters in the OrderNumber column. How can I do that?
I use migration when I'm creating this table
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Orders",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
UserId = table.Column<int>(type: "int", nullable: false),
MedicineId = table.Column<int>(type: "int", nullable: false),
CourierId = table.Column<int>(type: "int", nullable: false),
ReadyForDelivery = table.Column<bool>(type: "bit", nullable: false),
OrderNumber = table.Column<string>(type: "nvarchar(max)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Orders", x => x.Id);
});
}

Related

foreign key camel case issue in postgres on heroku server

i am creating table on heroku successfully but the problems is foreign key when add foreign key it will automatically created in small letter by default
postgres accept foreign key like serviceId format
this is my table
CREATE TABLE service_categories (
id serial PRIMARY KEY,
"serviceId" integer NOT NULL,
service_category_name VARCHAR ( 50 ) NOT NULL,
"createdAt" TIMESTAMP DEFAULT NOW(),
"updatedAt" TIMESTAMP DEFAULT NOW()
);
but on heroku its created serviceid rather then serviceId
any body can help how can i create foreign key like serviceId
just double quotes in the model like
const Order = db.define("my_orders", {
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true,
},
"serviceSubCategoryId": {
type: Sequelize.INTEGER
},
"userId": {
type: Sequelize.INTEGER
}
});

Insert Data from Json to multiple SQL tables with FK's

I want to get the data from a single JSON File to my SQL Database with multiple Tables.
This is the JSON File:
{
"Leads":
[
{
"id": "7dc31998-eb32-4171-a118-79837a2950ff",
"productId": "c7f3ba6f-5f8a-4472-8c03-000000000001",
"created": "2020-10-22T07:48:04.318123",
"customer": {
"city": "Hamburg",
"dateOfBirth": "1979-01-01",
"email": "max#mustermann.de",
"firstName": "max",
"netIncome": "FROM_1000_TO_1500",
"number": "123",
"occupation": "EMPLOYEE",
"phone": "+49 171 000 000 00",
"purchasePhase": "EVALUATING",
"street": "Spaldingstr.",
"surName": "mustermann",
"zip": "20097"
},
"request": {
"additionalCosts": 100000,
"brokerageFee": 0.068,
"city": "Stade",
"constructionType": "FOREIGN",
"cost": 500000,
"equity": 200000,
"financingRate": 0.066,
"kfwPromotion": true,
"loan": 400000,
"notaryFee": 0.02,
"realEstateTransferTax": 0.05,
"realEstateType": "APARTMENT",
"realEstateUsage": "RENT",
"zip": "21680"
}
},
{
"id": "7dc31205-eb32-4171-a118-79837a29abcd",
"productId": "c7f3ba6f-5f8a-4472-8c03-000000000001",
"created": "2020-10-23T07:48:04.318123",
"customer": {
"city": "Nürnberg",
"dateOfBirth": "1983-08-16",
"email": "mike#test.com",
"firstName": "Michael",
"netIncome": "FROM_2000_TO_2500",
"number": "123",
"occupation": "EMPLOYEE",
"phone": "+49 171 000 000 00",
"purchasePhase": "EVALUATING",
"street": "Spaldingstr.",
"surName": "mustermann",
"zip": "20097"
},
"request": {
"additionalCosts": 100000,
"brokerageFee": 0.068,
"city": "Stade",
"constructionType": "FOREIGN",
"cost": 500000,
"equity": 200000,
"financingRate": 0.066,
"kfwPromotion": true,
"loan": 400000,
"notaryFee": 0.02,
"realEstateTransferTax": 0.05,
"realEstateType": "APARTMENT",
"realEstateUsage": "RENT",
"zip": "21680"
}
}
]
}
This is my customer Table with customerID as Primary Key:
CREATE TABLE [dbo].[Customer] (
[customerID] INT IDENTITY (1, 1) NOT NULL,
[city] NVARCHAR (50) NULL,
[dateOfBirth] DATE NULL,
[email] NVARCHAR (50) NULL,
[firstName] NVARCHAR (50) NULL,
[netIncome] NVARCHAR (50) NULL,
[number] INT NULL,
[occupation] NVARCHAR (50) NULL,
[phone] NVARCHAR (50) NULL,
[purchasePhase] VARCHAR (50) NULL,
[street] NVARCHAR (50) NULL,
[surName] NVARCHAR (50) NULL,
[zip] INT NULL,
PRIMARY KEY CLUSTERED ([customerID] ASC)
);
The Request Table with requestID as Primary Key:
CREATE TABLE [dbo].[Request] (
[requestID] INT IDENTITY (1, 1) NOT NULL,
[additionalCosts] INT NULL,
[brokerageFee] DECIMAL (18) NULL,
[city] NVARCHAR (50) NULL,
[constructionType] NVARCHAR (50) NULL,
[cost] INT NULL,
[equity] INT NULL,
[financingRate] DECIMAL (18) NULL,
[kfwPromotion] NVARCHAR (50) NULL,
[loan] INT NULL,
[notaryFee] DECIMAL (18) NULL,
[realEstateTransferTax] DECIMAL (18) NULL,
[realEstateType] NVARCHAR (50) NULL,
[realEstateUsage] NVARCHAR (50) NULL,
[zip] INT NULL,
PRIMARY KEY CLUSTERED ([requestID] ASC)
);
the Leads Table:
CREATE TABLE [dbo].[Leads] (
[id] NVARCHAR (50) NOT NULL,
[productID] NVARCHAR (50) NULL,
[created] DATETIME2 (7) NULL,
[customerID] INT NULL,
[requestID] INT NULL,
PRIMARY KEY CLUSTERED ([id] ASC),
CONSTRAINT [FK_Leads_Customer] FOREIGN KEY ([customerID]) REFERENCES [dbo].[Customer] ([customerID]),
CONSTRAINT [FK_Leads_Request] FOREIGN KEY ([requestID]) REFERENCES [dbo].[Request] ([requestID])
);
and my Stored SQL Procedure:
alter Procedure prcInsertCustomer
(#json NVARCHAR(MAX) = '')
AS
BEGIN
DECLARE #LASTcustomerID int = 0
DECLARE #LASTRequestID int = 0
INSERT INTO dbo.Customer
SELECT city, dateOfBirth, email, firstName, netIncome, number, occupation, phone, purchasePhase, street, surName, zip
FROM OPENJSON(#json, '$.Leads')
WITH (
city NVARCHAR(50) '$.customer.city',
dateOfBirth date '$.customer.dateOfBirth',
email NVARCHAR(50) '$.customer.email',
firstName NVARCHAR(50) '$.customer.firstName',
netIncome NVARCHAR(50) '$.customer.netIncome',
number int '$.customer.number',
occupation NVARCHAR(50) '$.customer.occupation',
phone NVARCHAR(50) '$.customer.phone',
purchasePhase NVARCHAR(50) '$.customer.purchasePhase',
street NVARCHAR(50) '$.customer.street',
surName NVARCHAR(50) '$.customer.surName',
zip int '$.customer.zip'
)
SET #LASTcustomerID = IDENT_CURRENT('dbo.customer')
INSERT INTO dbo.Request
SELECT additionalCosts, brokerageFee, city, constructionType, cost, equity, financingRate, kfwPromotion, loan, notaryFee, realEstateTransferTax, realEstateType, realEstateUsage, zip
FROM OPENJSON(#json, '$.Leads')
WITH (
additionalCosts int '$.request.additionalCosts',
brokerageFee decimal(18,0) '$.request.brokerageFee',
city NVARCHAR(50) '$.request.city',
constructionType NVARCHAR(50) '$.request.constructionType',
cost int '$.request.cost',
equity int '$.request.equity',
financingRate decimal(18,0) '$.request.financingRate',
kfwPromotion NVARCHAR(50) '$.request.kfwPromotion',
loan int '$.request.loan',
notaryFee decimal(18,0) '$.request.notaryFee',
realEstateTransferTax decimal(18,0) '$.request.realEstateTransferTax',
realEstateType NVARCHAR(50) '$.request.realEstateType',
realEstateUsage NVARCHAR(50) '$.request.realEstateUsage',
zip int '$.request.zip'
)
SET #LASTRequestID = IDENT_CURRENT('dbo.Request')
INSERT INTO dbo.Leads
SELECT id, productId, created, #LASTcustomerID, #LASTRequestID
FROM OPENJSON(#json, '$.Leads')
WITH (
id NVARCHAR(50) '$.id',
productId NVARCHAR(50) '$.productId',
created datetime2(7) '$.created'
)
END
Now every time I run my stored procedure I have the Same IDs in both Leads:
And I need to proceed all Lead Items from JSON in ONE run.

Category and Sub-Categories with NodeJS and SQL Result

I am trying to build a JSON with NodeJS and SQL result.
The database is:
CREATE TABLE category (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
title varchar(255) NOT NULL,
parent_id int(10) unsigned DEFAULT NULL,
PRIMARY KEY (id),
FOREIGN KEY (parent_id) REFERENCES category (id)
ON DELETE CASCADE ON UPDATE CASCADE
);
CREATE TABLE `items` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`cat_id` int unsigned DEFAULT NULL,
`parent_id` int unsigned DEFAULT NULL,
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
PRIMARY KEY (`id`),
KEY `cat_id` (`cat_id`),
KEY `sub_id` (`parent_id`),
CONSTRAINT `cat_id` FOREIGN KEY (`cat_id`) REFERENCES `category` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `sub_id` FOREIGN KEY (`parent_id`) REFERENCES `category` (`parent_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
BEGIN;
INSERT INTO `category` VALUES (1, 'Colazione', NULL);
INSERT INTO `category` VALUES (2, 'Pranzo', NULL);
INSERT INTO `category` VALUES (3, 'Primi piatti', 2);
INSERT INTO `category` VALUES (4, 'Second dish', 2);
INSERT INTO `category` VALUES (5, 'Other things for lunch', 2);
COMMIT;
-- ----------------------------
-- Records of items
-- ----------------------------
BEGIN;
INSERT INTO `items` VALUES (1, 1, NULL, 'Cornetto');
INSERT INTO `items` VALUES (2, 3, 2, 'Pasta al sugo 1');
INSERT INTO `items` VALUES (3, 3, 2, 'Pasta al sugo 2');
INSERT INTO `items` VALUES (4, 3, 2, 'Pasta al sugo 3');
INSERT INTO `items` VALUES (5, 3, 2, 'Pasta al sugo 1 X');
INSERT INTO `items` VALUES (6, 3, 2, 'Pasta al sugo 2 X');
INSERT INTO `items` VALUES (7, 4, 2, 'Pasta al sugo 3 X');
COMMIT;
SET FOREIGN_KEY_CHECKS = 1;
The expected JSON is:
Category:
Sub-Categories:
Items:
If category doesn't got any sub-categories it will print:
Category:
Items:
We got more than one categories and each categories can have more than one sub-categories.
Each sub-categories can have more than one item.
How can I build a JSON result with NodeJS with SQL Query?
Expected JSON:
{
"menu": {
"categories": [
{
"id_category": 1,
"category_title": "Colazione",
"items": [
{
"id_item": 1,
"title": "Cornetto"
}
]
},
{
"id_category": 2,
"category_title": "Pranzo",
"subcategories": [
{
"title_subcategories": "Primi piatti",
"items": [
{
"id_item": 1,
"title": "Pasta al sugo 1"
},
{
"id_item": 2,
"title": "Pasta al sugo 2"
}
]
},
{
"title_subcategories": "Secondi piatti",
"items": [
{
"id_item": 1,
"title": "Pasta al sugo 3"
}
]
}
]
}
]
}
}
Here's what I came up with, although I haven't tested it:
async function buildJson(categories, items) {
// `query` is some function that queries the DB
const categries = await query('SELECT id AS id_category, title AS category_title, parent_id FROM categories');
const items = await query('SELECT id AS id_item, title AS item_title, cat_id FROM items');
const data = {
menu: {
categories: [],
},
};
const subcategories = categories.filter(category => category.parent_id !== null);
categories.filter(category => category.id_parent === null)
.forEach(category => {
data.menu.categories.push({
id_category: category.id_category,
category_title: category.category_title,
});
data.menu.categories.forEach(_category => {
_category.items = items.filter(item => item.cat_id === _category.id_category)
.map(item => ({
id_item: item.id_item,
title: item.title,
}));
_category.subcategories = categories.filter(__category => __category.parent_id === _category.id);
_category.subcategories.forEach(subcategory => {
subcategory.items = items.filter(item => item.cat_id === subcategory.id_category)
.map(item => ({
id_item: item.id_item,
title: item.title,
}));
});
});
});
return data;
}

Select a specific entry in json with PostgreSQL

I have the following JSON which is stored in a jsonb field named "Data" in a PostgreSQL database:
{
"CompetitionData" :
{
"StartDate" : "12.06.2018",
"Name" : "TestCompetition",
"Competitors" :
[
{
"Id" : "100",
"Name" : "John",
"Age" : "24",
"Score" : "98",
"Shoes":
{
"Brand" : "Nike"
}
},
{
"Id" : "200",
"Name" : "Adam",
"Age" : "32",
"Score" : "78",
"Shoes":
{
"Brand" : "Adidas"
}
}
]
}
}
Im trying to get a specific entry in Competitors, like e.g.
SELECT * FROM Competitors WHERE Shoes = "Nike";
And the result must look like this:
{
"Id" : "100",
"Name" : "John",
"Age" : "24",
"Score" : "98",
"Shoes":
{
"Brand" : "Nike"
}
}
I tried the following query, but i keeps returning all competitors:
SELECT jsonb_array_elements(public."Competitions"."Data"->'CompetitionData'->'Competitors') as test
FROM public."Competitions" WHERE public."Competitions"."Data" #> '{"CompetitionData":{"Competitors":[{"Shoes":{"Brand":"Nike"}}]}}';
Is it possible to return just the competitor with Shoe Brand "Nike" ?
Use jsonb_array_elements in the from clause
SELECT j.* FROM
t cross join lateral
jsonb_array_elements(data->'CompetitionData'->'Competitors') as j(comp)
where j.comp->'Shoes'->>'Brand' = 'Nike'
Demo
Why do you want to save it in jsonb? Just normalize it into a database:
CREATE TABLE competitor_shoe (
name text PRIMARY KEY,
brand text NOT NULL
);
CREATE TABLE competitor (
id int PRIMARY KEY,
name text NOT NULL,
age int NOT NULL,
score int NOT NULL,
shoe text NOT NULL REFERENCES competitor_shoe(name)
);
CREATE TABLE competition (
name text PRIMARY KEY,
start_date date NOT NULL
);
CREATE TABLE competition_competitor (
competition text REFERENCES competition,
competitor int REFERENCES competitor,
PRIMARY KEY (competition,competitor)
);
INSERT INTO competitor_shoe
VALUES ('shoes1', 'Nike'),
('shoes2', 'Adidas');
INSERT INTO competitor
VALUES (100,'John',24,98,'shoes1'),
(200,'Adam',32,78,'shoes2');
INSERT INTO competition
VALUES (
'TestCompetition',
'12.06.2018'
);
INSERT INTO competition_competitor
VALUES ('TestCompetition', 100), ('TestCompetition', 200);
-- query the data
SELECT *
FROM competitor c
JOIN competitor_shoe cs
ON c.shoe = cs.name
WHERE brand = 'Nike';
-- query the data and return it as json object
SELECT to_jsonb(c) || jsonb_build_object('shoe', to_jsonb(cs)) as data
FROM competitor c
JOIN competitor_shoe cs
ON c.shoe = cs.name
WHERE brand = 'Nike';

Laravel Eloquent ORM for Social Network

I have the following database setup for my status posts. For each post, users can like the post, comment on the post or can even be tagged in the original post by the author.
I'm trying to setup my Resourceful controller 'Post' to bring back all the data via JSON object but I can't properly find the comment, likes or tags usernames. I'm using Sentry 2 for auth if that makes a difference.
Here's the database setup:
CREATE TABLE Users (
id INT NOT NULL AUTO_INCREMENT,
first_name VARCHAR(30),
last_name VARCHAR(30),
many more...
);
CREATE TABLE Posts (
postID INT NOT NULL AUTO_INCREMENT,
caption VARCHAR(200),
description VARCHAR(200),
fromID INT(10) UNSIGNED NOT NULL,
toID INT(10) UNSIGNED NOT NULL,
icon VARCHAR(200),
link VARCHAR(200),
message TEXT,
storyType INT,
type ENUM ('LINK', 'PHOTO', 'STATUSUPDATE', 'VIDEO' ),
createdTime DATE,
PRIMARY KEY (postID),
FOREIGN KEY (fromID) REFERENCES users (id),
FOREIGN KEY (toID) REFERENCES users (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE Likes (
likeID INT NOT NULL AUTO_INCREMENT,
fromID INT(10) UNSIGNED NOT NULL,
postID INT NOT NULL,
createdDate DATE,
PRIMARY KEY (likeID),
FOREIGN KEY (fromID) REFERENCES users (id),
FOREIGN KEY (postID) REFERENCES Posts (postID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE Comments (
commentID INT NOT NULL AUTO_INCREMENT,
fromID INT(10) UNSIGNED NOT NULL,
postID INT NOT NULL,
comment TEXT,
createdDate DATE,
PRIMARY KEY (commentID),
FOREIGN KEY (fromID) REFERENCES users (id),
FOREIGN KEY (postID) REFERENCES Posts (postID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE Tags (
tagID INT NOT NULL AUTO_INCREMENT,
userID INT(10) UNSIGNED NOT NULL,
postID INT NOT NULL,
PRIMARY KEY (tagID),
FOREIGN KEY (userID) REFERENCES users (id),
FOREIGN KEY (postID) REFERENCES Posts (postID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
My Post Controller, I just have a simple page that spits out everything. I don't want to loop through anything in my view file, I just want to bring back the json full object.
class PostController extends BaseController {
public function show($id)
{
$post = Post::with(array('comments', 'from', 'tags', 'likes'))->find($id);
return View::make('samplepage')->with('data', $post);
}
}
My Post Model:
class Post extends Eloquent {
protected $table = 'Posts';
protected $primaryKey = 'postID';
public function comments()
{
return $this->hasMany('Comment','postID');
}
public function tags()
{
return $this->hasMany('Tag','postID');
}
public function likes()
{
return $this->hasMany('Like','postID');
}
public function from()
{
return $this->belongsTo('User', 'fromID')->select(array('id', 'first_name', 'last_name'));
}
public function users()
{
return $this->belongsTo('User', 'fromID');
}
}
Comment Model:
class Comment extends Eloquent {
protected $table = 'Comments';
protected $primaryKey = 'commentID';
public function post() {
return $this->belongsTo('Post','fromID');
}
public function user() {
return $this->belongsTo('User', 'fromID')->select(array('id', 'first_name', 'last_name'));
}
}
Tag Model:
class Tag extends Eloquent {
protected $table = 'Tags';
protected $primaryKey = 'tagID';
}
I even setup the following in my user model but it makes no difference.
User Model:
public function posts() {
return $this->hasMany('Post','id');
}
public function comments() {
return $this->hasMany('Comment','id');
}
Everything works great with this setup and when I hit posts/2 with this the following code, I get the below object back.
$post = Post::with(array('comments', 'from', 'tags', 'likes'))->find($id);
return View::make('samplepage')->with('data', $post);
{
postID: "2",
toID: "8",
comments: [
{
commentID: "2",
comment: "second comment",
fromID: "1",
postID: "2",
createdDate: "2014-02-15"
}
],
from: {
id: "4",
first_name: Paul,
last_name: Davis
},
tags: [
{
tagID: "1",
userID: "2",
postID: "2"
},
{
tagID: "2",
userID: "3",
postID: "2"
}
],
likes: [
{
likeID: "1",
fromID: "2",
postID: "2",
createdDate: "2013-01-04"
},
{
likeID: "2",
fromID: "3",
postID: "2",
createdDate: "2013-02-05"
}
]
}
But what I want is the following, where for each tag, like and comment to concatenate the first and last name and get them back with the object.
{
postID: "2",
toID: "4",
comments: [
{
commentID: "2",
comment: "second comment",
fromID: "1",
from: {
"name": "Jason Terry",
"id": "721286625"
},
postID: "2",
createdDate: "2014-02-15"
}
],
from: {
id: "4",
first_name: Paul,
last_name: Davis
},
tags: [
{
tagID: "1",
userID: "2",
from: {
"name": "David Lee",
"id": "721286625"
},
postID: "2"
},
{
tagID: "2",
userID: "3",
from: {
"name": "Paul Pierce",
"id": "721286625"
},
postID: "2"
}
],
likes: [
{
likeID: "1",
fromID: "2",
from: {
"name": "David Lee",
"id": "721286625"
},
postID: "2",
createdDate: "2013-01-04"
},
{
likeID: "2",
fromID: "3",
from: {
"name": "Al Davis",
"id": "721286625"
},
postID: "2",
createdDate: "2013-02-05"
}
]
}
I have searched Stackoverflow, countless Laravel blogs, the official documentation for 2 weeks now and I can't seem to solve this. Any help is wonderfully appreciate.
Update:
With Tony's answer below I added
$post = Post::with(array('comments.users', 'from', 'tags.users', 'likes.users'))->find($id);
Then I added
public function users()
{ return $this->belongsTo('User', 'fromID')->select(array('id', 'first_name', 'last_name'));
}
to the comments, tags, and likes model. And the object works great now.
But my debugger shows the following
select `id`, `first_name`, `last_name` from `users` where `users`.`id` in ('1')
select `id`, `first_name`, `last_name` from `users` where `users`.`id` in ('4')
select `id`, `first_name`, `last_name` from `users` where `users`.`id` in ('2', '3')
select `id`, `first_name`, `last_name` from `users` where `users`.`id` in ('2', '3')
In short, it runs 4 queries on my users table. Isn't this redundant? Shouldn't it be doing 1 query to the users table instead of 1 query for the original post user, 1 query for the comments users, 1 query for the tags users, and 1 query for the likes users?
It looks like you want to use nested relationships.
$post = Post::with('comments.from', 'from', 'tags.from', 'likes.from')->find($id);
You would also need the "from" relationship coded into each of those models.
To get your concatenated name; you'd need the following in your User model
protected $appends = array('name');
protected $hidden = array('first_name', 'last_name'); //this is optional
public function getNameAttribute()
{
return $this->attributes['first_name'] . ' ' . $this->attributes['last_name'];
}
it is little old post but you can also do this,
public function from()
{
return $this->belongsTo('User', 'fromID')
->select(array('id',DB::raw("CONCAT(firstname,' ', lastname) as name")));
}