Retrieve data from SP inside of From - stored-procedures

I would like to use [sp_Test] to retrieve the data from the syntax code "FROM" but it does not work. Do you know how to solve it?
Thanks!
create table datatable (id int,
name varchar(100),
email varchar(10),
phone varchar(10),
cellphone varchar(10),
none varchar(10)
);
insert into datatable values
(1, 'productname', 'A', 'A', 'A', 'A'),
(2, 'cost', '20', 'A', 'A', 'A'),
(3, 'active', 'Y', 'A', 'A', 'A');
insert into datatable values
(4, 'productname', 'A', 'A', 'A', 'A'),
(5, 'cost', '20', 'A', 'A', 'A'),
(6, 'active', 'Y', 'A', 'A', 'A');
insert into datatable values
(7, 'productname', 'A', 'A', 'A', 'A'),
(8, 'cost', '20', 'A', 'A', 'A'),
(9, 'active', 'Y', 'A', 'A', 'A');
CREATE PROCEDURE [sp_Test]
as
begin
set nocount on
SELECT a.name, a.email, a.phone
FROM datatable a
end

First you should never name your stored procedure with sp_ prefix. It is very bad habit and can collide with system stored procedures.
Second you cannot simply use SELECT FROM EXEC, but you can create temporary table/variable to hold result and query it like:
DECLARE #t AS TABLE ( name varchar(100),
email varchar(10),
phone varchar(10));
INSERT INTO #t
EXEC [dbo].[sp_Test];
SELECT *
FROM #t;
SqlFiddleDemo
There is also workaround using loopback linked server and OPENQUERY:
SELECT *
FROM OPENQUERY(LOCALSERVER, 'EXEC [sp_Test]');
I strongly recommend to read:
How to Share Data between Stored Procedures
Why is selecting from stored procedure not supported in relational databases?.

Related

Get result from multiple result-JOIN or Union?

I am a newbie on the database side.
I have three tables. as per the below screen.
I want to create a view that shows records from job_document and engineer_certficate tables
job document holds, manually uploaded document info and enginnner_certficate holds document data filled out by the android application.
On UI, I want to show available documents from both tables. I tried with "join" but did not get the expected result.
SELECT * FROM document_type d join job_document jd ON jd.document_type_id = d.id JOIN `engineer_certficate` ec on ec.document_type_id = d.id ;
I have also tries Union, but still no luck
Expected Result
Show all columns of job_document and engineer_certficate
CREATE TABLE `document_type` ( `id` int(5) NOT NULL, `name` varchar(55) NOT NULL, `description` varchar(255) NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=latin1; INSERT INTO `document_type` (`id`, `name`, `description`) VALUES (1, 'A', ''),(2, 'B', ''),(3, 'C', ''),(4, 'D', ''); CREATE TABLE `engineer_certficate` ( `id` int(10) NOT NULL, `job_id` int(10) NOT NULL, `document_type_id` mediumint(4) NOT NULL, `certficate_info` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL CHECK (json_valid(`certficate_info`))) ENGINE=InnoDB DEFAULT CHARSET=latin1; INSERT INTO `engineer_certficate` (`id`, `job_id`, `document_type_id`, `certficate_info`) VALUES(1, 1, 2, '{\"test\":\"abc\"}'),(2, 2, 2, '{\"test\":\"abc\"}'); CREATE TABLE `job_document` ( `id` int(10) NOT NULL, `job_id` int(10) NOT NULL, `document_type_id` mediumint(4) NOT NULL, `document_label` varchar(55) NOT NULL, `document_path` varchar(500) NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=latin1; INSERT INTO `job_document` (`id`, `job_id`, `document_type_id`, `document_label`, `document_path`) VALUES(1, 1, 1, 'DocA', '2022/02/doca.pdf'),(2, 1, 3, 'DocC', '2022/02/docc.pdf');
ALTER TABLE `document_type` ADD PRIMARY KEY (`id`); ALTER TABLE `engineer_certficate` ADD PRIMARY KEY (`id`); ALTER TABLE `job_document` ADD PRIMARY KEY (`id`);

Active record: filter on distinct value

I have several entries in a table in my RoR app:
{id: 1, item_id: a, ...}
{id: 2, item_id: a, ...}
{id: 3, item_id: a, ...}
{id: 4, item_id: b, ...}
{id: 5, item_id: b, ...}
{id: 6, item_id: c, ...}
{id: 7, item_id: d, ...}
{id: 8, item_id: d, ...}
I would like to create a query that filters on distinct item_id and returns the first matching entry, so that the result would be
{id: 1, item_id: a, ...}
{id: 4, item_id: b, ...}
{id: 6, item_id: c, ...}
{id: 7, item_id: d, ...}
When using
select(:item_id).distinct
I cannot access the other attributes of the entries. How can this be accomplished?
If you just want to get the lowest id for every item_id, you could use an aggregate query to retrieve these ids:
grouped_with_min_id = Model.group(:item_id).minimum(:id)
rows = Model.find(grouped_with_min_id.map(&:id))
This may not be the most efficient solution as it uses two queries. But other methods will probably require you to use Model.find_by_sql and write your own sql.
Disclaimer: I did not try that out.

Insert multiple records with join

I need some help in figuring out how to insert more than one records in a table using a join (when the join returns more than one values). So here is the scenerio:
Table A:
A_ID bigserial, Role Varchar(25), Description varchar(25)
Table B:
B_ID bigserial, Role Varchar(25), Code varchar(25)
Table A and B are connected with column Role.
Example Entries in Table_A:
1, A, Standard
2, B , Test
3, C, Test
4, D, Standard
Example Entries in Table_B:
1, A, ABC
2, B, XYZ
3, C, XYZ
4, D, ABC
Basically what I need to do is check for Roles where description = Test, then insert entry for this Custom Role to Table_B with Code = ABC (If entry doesn't exist already)
The following query will give me all the Test description Roles which do not have any entry with Code = ABC in table B
Query1:
SELECT ROLE FROM TABLE_A A
INNER JOIN TABLE_B B
ON A.ROLE=B.ROLE
WHERE A.Description ='Test'
AND B.CODE<>'ABC';
I have the following insert query:
insert into Table_B (Role , Code)
select (SELECT ROLE FROM TABLE_A A
INNER JOIN TABLE_B B
ON A.ROLE=B.ROLE WHERE A.Description ='Test'AND B.CODE<>'ABC'), 'ABC';
The above insert query only works when Query1 returns one role, however I am not sure how to insert into table_A when Query1 returns more than 1 results.
Can someone pls help? Not looking to use Stored Procs for the same
Thanks.
Edited:
Example Entries in Table_A:
1, A, Standard
2, B , Test
3, C, Test
4, D, Standard
5, E, TEST
Example Entries in Table_B:
1, A, ABC
2, B, XYZ
3, B, ABC
4, C, DEF
5, C, XYZ
6, D, ABC
7, E, XYZ
8, E, LLL
Query1 will not work here:
SELECT ROLE FROM TABLE_A A
INNER JOIN TABLE_B B
ON A.ROLE=B.ROLE
WHERE A.Description ='Test'
AND B.CODE<>'ABC';
Using this query now:
SELECT distinct ROLE FROM TB where role not in (
SELECT B.ROLE FROM TA A
INNER JOIN TB B
ON A.ROLE=B.ROLE
WHERE A.Description =Test
AND B.CODE=ABC)
and role in (select role from TA where Description =Test);
How will the insert work now?
You can make another column as 'Code'.
Something like:
insert into Table_B (Role , Code)
SELECT ROLE, 'ABC' CODE FROM TABLE_A A
INNER JOIN TABLE_B B
ON A.ROLE=B.ROLE WHERE A.Description ='Test' AND B.CODE<>'ABC';
So number of columns will be match.

Cypher zip collections

If I have two collections, how might I zip them together?
with [1,2,3] as nums, ['a', 'b', 'c'] as letters
... wat do? ...
return zipped // [{a: 1}, {b: 2}, {c: 3}]
It may not be possible to dynamically assign map keys (e.g., using the items in letters). But this query will return something similar to what you want (using collections instead of maps):
WITH [1,2,3] as nums, ['a', 'b', 'c'] as letters
RETURN EXTRACT(i IN RANGE(0, LENGTH(nums) - 1) | [letters[i], nums[i]]) AS result;
The result is:
[["a",1],["b",2],["c",3]]

How to model differing criteria?

I need to be able to match prospective owners to abandoned animals based on varying criteria and locations.
The owner will have a particular criteria set. Animal type = "dog", breed = "Labrador Retriever", age will need to be between 1 and 5, sex = male, and so on...
The animal will also have a particular criteria set. The animal type = "Dog", age = 3, sex = male, breed = "Chihuahua".
The animal could also be: type = "Cat", age = "12", sex = female, breed = "Tiger".
I also have a "Location" model for both the owner and the animal (polymorphic) that contains the information related to the location of either the animal or the owner.
So that part is easy...
The hard part (at least for me) is when I need to specify different criteria for different animal types. So an animal of type = "dog" may have a criteria of "can fetch?" whereas an animal of type cat may have a criteria of "de-clawed?" and a animal of type "fish" may have criteria of "pattern" with multiple options of ["speckled", "striped", "plain"].
What I have now is an "animal" model with the generic animal information (age, sex, breed), then I have a breeds model with the various breeds per animal type, but I can't figure out how to abstract out the criteria that differs between the animal types.
Again, this is just an analogy because I don't think my actual problem will make any sense to anyone else. What I need is just some pointers in the right direction, maybe a link or two. I just can't seem to work out how to make this happen in Rails without creating a separate table for each criteria set, as in dog_criteria, cat_criteria, fish_criteria, and so on...
Sometimes we resort to simple name/value pairs (or name/value/type triples ) for such properties. This saves adding new types (and database tables) for every animal species in the world. Or worse for each breed: Consider poodles ... they might have an extra field "shaved decoratively" ... and St Bernards, brandy capacity ...
In the software modeling world, this would obviously be done with a class for each species, I.E. "Dog", "Cat", "Fish" which extend "Animal". In the relational database world, this becomes a bit harder to represent.
If you wanted to match this object-oriented approach in your database, you would have a table for "Animals" and then a table for each species, "Cat", "Dog", and "Fish". Then you would probably have a species table (or a hard-coded enum in your code) that would give you a value to place in the Animal row for which species each animal was. This would tell you how to look up further information for each animal.
This is probably not the best approach. What you have is more what I would call "Custom Data" for each animal. You should define one table that has a list of custom attributes, and another table to match these attributes to a value for each animal row.
If you'd like to make it more convenient to see and control which attributes can apply to which species you could make a third table for "Categories" which would link to the Animal species and to a collection of attributes. Then you would specify the category ID on the animal row.
Sample tables:
Animals
-------
ID
Age
Sex
Species
Breed
Parameters
----------
ID
Name
Parameter Values
----------------
ParameterID
AnimalID
Value
Categories (optional - add CategoryID to animals)
---------------------
ID
Name
Category Parameters
-------------------
CategoryID
ParameterID
The name value pair solution can be done within the database.
In this example there are 4 tables, person, requirement, pet, petstat
Person and Pet each have an id and a name.
Each person also has one or more requirements. Requirements have a name, comparison, and a value.
Each pet has one or more PetStats which consist of a name and a value
with this setup, the short haired dogs could be found with a query like :
select * from pet, petstat
where pet.id = petstat.petId
and petstat.name = 'hair'
and petstat.value = 'short'
and petId in (select petId from petstat
where name='type' and value = 'dog')
The following query will match people to pets when all of the person's requirements are met by a pet.
select person.name, pet.name from person, pet
where (select count(*) from requirement where requirement.personid = person.id)
= (select count(*) from requirement, petstat
where requirement.comparison = 'eq'
and requirement.name = petstat.name
and requirement.value = petstat.value
and requirement.personId = person.id
and petstat.petid = pet.id)
+ (select count(*) from requirement, petstat
where requirement.comparison = 'lt'
and requirement.name = petstat.name
and requirement.value > petstat.value
and requirement.personId = person.id
and petstat.petid = pet.id)
+ (select count(*) from requirement, petstat
where requirement.comparison = 'gt'
and requirement.name = petstat.name
and requirement.value < petstat.value
and requirement.personId = person.id
and petstat.petid = pet.id);
The less than and greater than comparisons could be handled better by adding numeric fields to the requirement and petstat tables and adding more pieces to the query, but this gives a good stat.
Here are the inserts to create the test data.
delete from person;
insert into person (id, name) values (1, 'Joe');
insert into person (id, name) values (2, 'Bill');
insert into person (id, name) values (3, 'Erik');
insert into person (id, name) values (4, 'Mike');
delete from pet;
insert into pet (id, name) values (1, 'spot');
insert into pet (id, name) values (2, 'mittens');
insert into pet (id, name) values (3, 'rover');
delete from requirement;
insert into requirement (personid, name, comparison, value) values (1, 'type', 'eq', 'dog');
insert into requirement (personid, name, comparison, value) values (1, 'color', 'eq', 'black');
insert into requirement (personid, name, comparison, value) values (2, 'type', 'eq', 'fish');
insert into requirement (personid, name, comparison, value) values (3, 'type', 'eq', 'dog');
insert into requirement (personid, name, comparison, value) values (3, 'hair', 'eq', 'long');
insert into requirement (personid, name, comparison, value) values (4, 'type', 'eq', 'dog');
insert into requirement (personid, name, comparison, value) values (4, 'weight', 'lt', '30');
insert into requirement (personid, name, comparison, value) values (4, 'weight', 'gt', '20');
delete from petstat;
insert into petstat (petId, name, value) values (1, 'type', 'dog');
insert into petstat (petId, name, value) values (1, 'color', 'black');
insert into petstat (petId, name, value) values (1, 'hair', 'short');
insert into petstat (petId, name, value) values (2, 'type', 'cat');
insert into petstat (petId, name, value) values (3, 'type', 'dog');
insert into petstat (petId, name, value) values (3, 'weight', '25');
insert into petstat (petId, name, value) values (3, 'color', 'brown');

Resources