removing a multislot variable in JESS - jess

I have a deftemplate which contains a multislot in JESS and I want to delete a variable in the multilot if the rule is fired. for example:
(deftemplate Person (slot name)
(multislot friends))
(assert (Person (name John)(friends Jimmy Joe Jessica)))
now i want to delete Jimmy from the friends slot.
Thank you very much
Ali

I've fixed some omissions in your question, assuming that the template name is Person.
This rule eliminates Jimmy from all friends of all Persons.
(defrule KillJimmy
?p <- (Person (friends $?a Jimmy $?b))
=>
(modify ?p (friends (create$ $?a $?b)))
)

Related

MySQL: sort so that the rows are brought together after column A but the groups odered after the greatest corresponding value in column B

For a dummy example, let's say that I have a database with following rows: book, author (=column A), publish-date (=column B).
Now, I want to sort the books so that the rows are brought together by author, but the authors have to appear in such order that the author having published the most recently comes first. For each author the books have to be sub-sorted by publishing date.
Output example I would like to have:
BOOK AUTHOR PUBLISH-DATE # COMMENT
some book John Doe 2019 # most recent book => John Doe is first
another book John Doe 2017
one more John Doe 2011
again a book Richard Roe 2016 # Richard Roe is second because this is the most recent book amongst the remaining ones.
and one more Richard Roe 2008
another one Janie Doe 2013 # and so on.
(Explanation of the above example : John Doe comes first because he wrote a book most recently. But his other books are displayed immediately afterwards, sorted by publishing date in reversed order. Then comes Richard Roe because he is the second most recent author that published a book. And so on.)
Basically, instead of sorting with ORDER BY author ASC, publish-date DESC, I would like to reorder the groups of books by a given author after the biggest value in the third column.
I have no clue how to solve this in MySQL nor do I know how this kind of sorting is called. I hope you can help me out ^^ Thanks in advance !
One method is a correlated subquery:
select t.*
from t
order by (select max(t2.publish_date)
from t t2
where t2.author = t.author
);
MySQL 8+ (and standard SQL) has a much simpler method using window functions:
select t.*
from t
order by max(publish_date) over (partition by author)
You must order first by each author's latest publishdate and then by publishdate descending:
select b.*
from books b
order by (
select max(publishdate)
from books
where author = b.author
) desc, b.publishdate desc

SQL: Pulling information based on two other columns

Please bear with me, this is a little difficult to explain:
Trying to find a way to pull names that contains "Op" in "Type" column, but the "Code" values must be unique with "Type"
Such as: (Using the first 3 rows below)
Do not pull first or second row, because "SPX" is related to both "Com" and "Op", but pull row #3 because "VPA" only has "Op" in column "Type". So the values under "code" column cannot be in both "Op" and "Com" under type for the each account.
Input"
Name Type Code
John Com SPX
John Op SPX
John Op VPA
John Op SPX
Matt Op SPX
Matt Op SPX
Jane Com SPX
Jane Com SPR
Jack Op SPR
Jack Op SPX
Jack Com SPR
Output:
Name Type Code
John Op VPA
Matt Op SPX
Matt Op SPX
Jack Op SPX
Would greatly appreciate any help!
Thank you!
try this NOT EXISTS
select *
from
mytable t1
where not exists
(
select 1 from mytable t2
where t2.type = 'com'
and t2.name = t1.name -- if the name exists with a com type then exclude
)

MYSQL, is this kind of request possible?

I have persons (table person) who have 0 or N roles (tables role and personne_role).
I want to select all the persons , with the roles they have, to have this kind of result :
PHIL COLLINS | Drummer | Singer
MIKE RUTHERFORD | Singer
ION ANDERSON | Singer
MIKE JAGGER |
CARLOS SANTANA | Guitarist
......
Each line can have 0 or N roles.
To do that, I make 2 requests
the first one to get the employees (table person)
the second one to loop all the retrieved employees and retrieve each role of them (tables role and person_role)
It works BUT in the case of there are a lot of lines, it is not very efficient.
I would like the same result in 1 request.
Is it possible ?
What are the mysql keywords I must use to do that ?
Thanks for your feedback.
dominique
You could use a JOIN with a GROUP_CONCAT, something like:
SELECT person.name, role.roles
FROM person
LEFT JOIN (
SELECT person_id, GROUP_CONCAT(DISTINCT role SEPARATOR ' | ') roles
FROM person_role
GROUP BY person_id
) role ON (person.id = role.person_id)
EDIT: the fields name are just a guess, since you didn't show us the full table schema; also, if the roles are actually in a separate tale, say joined by a role_id, you'd need to add it to the subquery.

Return value from within a range in SQL Server 2008

I have two tables, one where it contains members & their cardnumbers, and outlet table which identifies the cardnumber ranges per outlet. I want to know which store the cardnumber the member has belongs to.
Members Table
MemberID Cardnumber FirstName LastName
1 123456123 John Doe
2 123456245 Sarah Smith
Outlets Table
OutletID OutletName StartCardNumber EndCardNumber
1 Balmain Store 123456100 123456200
2 Sydney Store 123456201 123456300
I can't think of a script which I can bring back the following information without having to
create a temp table first. Is there an easier way?
CardNumber FirstName LastName OutletName
123456123 John Doe Balmain Store
123456245 Sarah Smith Sydney Store
It's very simple. You join on a range using inequalities in addition to equalities.
SELECT
M.CardNumber,
M.FirstName,
M.LastName,
O.OutletName
FROM
dbo.Members M
INNER JOIN dbo.Outlets O
ON M.CardNumber >= O.StartCardNumber
AND M.CardNumber <= O.EndCardNumber
This is the same as M.CardNumber BETWEEN O.StartCardNumber AND O.EndCardNumber but I wanted to draw out the inclusive endpoints of your scheme using >= and <=. BETWEEN is not always suitable because very often the end value is exclusive requiring <, but not in this case.
Try this out right now online!

Need some advice to maintain a certain order within datasets within MySQL

Assume a list of names in a table called authors. Each author has written some books during his lifetime. Important: You don't know the explicit dates when the books were published. (If I would now the exact dates, I could just order by that in each query and I would be good.) You only know the order of the books' publication. The books are stored in a table books. We have a Many-To-Many-Relation between authors and books.
The question: How would you store the order of a publication history of each of the authors?
Example:
Luc - title_1
Luc - title_2
Luc - title_10
Luc - title_234
Peter - title_1
Peter - title_5
Peter - title_10
Peter - title_987
John - title_2
John - title_5
John - title_9
...
At the moment I am storing for each author a string of comma separated Values (primary keys of the books) to remember the order of the publications of a certain author in a column called books_order.
id name publication_order
...
4 john (2, 5, 9)
...
But that is certainly the wrong way to go. How to normalize that?
I would add an extra column called sortorder or somethin similar. The first book gets a 1, the second a 2 ... etc. With that, you can use ORDER BY author, sortorder to get a list of books sorted by author and order of publication.