Как меня всегда радуют люди, которые свято верят, что в мире нет энтерпрайза. Причём — это корневые системы и огромные фирмы, кодовая база и штат программистов которых очень велики.
Какие пет проекты могут быть у SQLщика? )
О каких новых фреймворках идёт речь, когда найти работу в крупной компании на Delphi 5-7 и SQL 2008 совершенно непроблема? )
О каком количестве кода за час идёт речь, когда мне больше всего платят как раз когда я УМЕНЬШАЮ кодовую базу или переписываю существующую? Или просто ПЛАНИРУЮ как я буду это делать? )
Многие программисты, с которыми мы работаем (наверняка, это и вас касается), не умеют, не любят, не хотят формулировать задачи в виде тикета — понятного и краткого.
Программисты формулируют задачи? Што? Может они их будут реализовывать, а формулировать и ставить специальные люди? (аналитики?) А то когда программист сам себе ставит задачи — это как то… опасненько.
Про английский язык — вообще жара. 15 лет программирую в разных проектах — ни разу не пригодился. Как в прочем и ни одному из коллег, кроме одного, который решил уехать за границу. Может я что то делаю не так? Или это речь о тех, кто работает фрилансом и по удалёнке? )
GitHub… да-да… опенсорс энтерпрайз решения… банки работающие на опенсорсных системах… государственные системы… ага-ага. И тем более делающие это через гитхаб. И, вдвойне, СОБИРАЮЩИЕ ФОЛОВЕРОВ. Боже.
А уж про то что нужно вокруг себя окружение собирать… зачем? Ну вот зачем?
Вопрос не в том, что ты имеешь право относительно других.
Вопрос в том, что ты чувствуешь в себе такое право.
Сказать начальнику, что он не прав, когда он не прав. (многие не могут для себя даже рассмотреть такую возможность, даже при лояльном начальнике)
Не оправдываться, когда ты прав или допустил ошибку, а просто признать её или отстоять свою правоту.
Многие не чувствуют в себе этого права и, как следствие копят в себе негатив, понижают самооценку и совершенно теряют связь с реальностью, когда им предоставляется возможность стать самостоятельной личностью, а не ведомой любым из окружающих людей.
Смысл статьи не в том, что бы устраивать бунт, или плевать начальству в лицо, а в том, что бы трезво оценивать свою правоту, иметь свою волю и быть живым человеком, а не подстилкой. Это делает людей эффективнее, увереннее в себе, инициативней, снижает стресс и увеличивает жизненный тонус. И не желать такого коллегам или подчинённым могут только те, кто активно пользуется человеческой беспомощностью.
with cte_friends as (
select
t.first_person_id,
t.second_person_id,
c.dummy_first_person_id,
c.dummy_second_person_id
from friends as t
cross apply (values
(t.first_person_id, t.second_person_id),
(t.second_person_id, t.first_person_id)
) as c(dummy_first_person_id, dummy_second_person_id)
)
Прогнал ваш запрос.
1. В нём есть много опечаток )
2. В нём проверка только на одностороннее неналичие в друзьях (насколько я понял)
3. План, в принципе, строится такой же. =D
4. Сравнивал Ваш вариант и свой и нашёл ещё ошибку. Да что за жизнь то )
;WITH PersonRelationShipCollapsed AS (
SELECT pl.PersonAID
,pl.PersonBID
,pl.Relation
FROM #PersonRelationShip AS pl
UNION
SELECT pl.PersonBID AS PersonAID
,pl.PersonAID AS PersonBID
,pl.Relation
FROM #PersonRelationShip AS pl
)
SELECT
pl.PersonAID
,pf.PersonBID
,pff.PersonBID
FROM #Persons AS p
--Лайки
JOIN PersonRelationShipCollapsed AS pl ON pl.PersonAID = p.PersonID
AND pl.Relation = 'Like'
--Друзья
JOIN PersonRelationShipCollapsed AS pf ON pf.PersonAID = p.PersonID
AND pf.Relation = 'Friend'
--Друзья Друзей
JOIN PersonRelationShipCollapsed AS pff ON pff.PersonAID = pf.PersonBID
AND pff.PersonBID = pl.PersonBID
AND pff.Relation = 'Friend'
--Ещё не дружат
LEFT JOIN PersonRelationShipCollapsed AS pnf ON pnf.PersonAID = p.PersonID
AND pnf.PersonBID = pff.PersonBID
AND pnf.Relation = 'Friend'
WHERE pnf.[PersonAID] IS NULL
А что у Вас вызывает сомнения в плане? )
Скорее всего он будет практически идентичен плану вашего запроса:
6 индекс сиков (в случае поиска по одной персоне) и два скана.
Или все 8 сканов, если поиск производится «вообще».
Возможно, с изменением статистики по таблицы план изменится в ту или иную сторону.
В любом случае — а кто вам сказал, что гипотетический функциональный язык сможет сделать это оптимальнее? )
Очевидно, что условия были не очень ясно указаны.
К примеру, несимметричные отношения, по моему пониманию, подразумевали что нужно брать только тех, кого Я лайкнул и кого выбрал другом человек, которого выбрал другом Я.
А те, кого я не лайкнул, а кто меня лайкал в таком случае не должны попасть в выборку.
Но если не важно направление связи — то я описал варианты чуть выше.
Спасибо за живое участие, посмотрите, вдруг я и там опечатался )
Руки никак не дойдут создать таки эти таблицы и сделать тесты. Работа-с.
К примеру
Связи хранятся в одностороннем виде.
т.е. если (условно) отношения представлены в виде двух строчек в таблице.
ID 12352 PersonAID 100 PersonBID 101 RelationShip 'Like'
ID 12353 PersonAID 101 PersonBID 100 RelationShip 'Like'
Если вы понимаете о чём я.
Тогда как то так:
;WITH PersonRelationShipCollapsed AS (
SELECT pl.PersonAID
,pl.PersonBI
,pl.Relation
FROM PersonRelationShip AS pl
UNION
SELECT pl.PersonBID AS PersonAID
,pl.PersonAID AS PersonBID
,pl.Relation
FROM PersonRelationShip AS pl
)
SELECT
pl.PersonAID
,pf.PersonAID
,pff.PersonAID
FROM Persons AS p
--Лайки
JOIN PersonRelationShipCollapsed AS pl ON pl.PersonAID = p.PersonID
AND pl.Relation = 'Like'
--Друзья
JOIN PersonRelationShipCollapsed AS pf ON pf.PersonAID = p.PersonID
AND pf.Relation = 'Friend'
--Друзья Друзей
JOIN PersonRelationShipCollapsed AS pff ON pff.PersonAID = pf.PersonBID
AND pff.PersonBID = pl.PersonBID
AND pff.Relation = 'Friend'
--Ещё не дружат
LEFT JOIN PersonRelationShipCollapsed AS pnf ON pnf.PersonAID = p.PersonID
AND pnf.PersonBID = pff.PersonBID
AND pnf.Relation = 'Friend'
WHERE pnf.PersonAID IS NULL
Хотел описать второй вариант, с экономией строк (когда в каждой строке хранится PersonAID, PersonBID, Relation и RelationTypeID: 1 от А к Б, 2 от Б к А, 3 — взаимно), но такой вариант сводится к первому на самом деле. =)
Я ниже уже привёл исправленный вариант, это была опечатка (реально, я бы использовал немного другие имена, что б не так сливались...)
Спасибо что указали )
К сожалению, вчерашний коментарий я не могу отредактировать =(
SELECT
pl.PersonAID
,pf.PersonAID
,pff.PersonAID
FROM Persons AS p
--Лайки
JOIN PersonRelationShip AS pl ON pl.PersonAID = p.PersonID
AND pl.Relation = 'Like'
--Друзья
JOIN PersonRelationShip AS pf ON pf.PersonAID = p.PersonID
AND pf.Relation = 'Friend'
--Друзья Друзей
JOIN PersonRelationShip AS pff ON pff.PersonAID = pf.PersonBID
AND pff.PersonBID = pl.PersonBID
AND pff.Relation = 'Friend'
--Ещё не дружат
LEFT JOIN PersonRelationShip AS pnf ON pnf.PersonAID = p.PersonID
AND pnf.PersonBID = pff.PersonBID
AND pnf.Relation = 'Friend'
WHERE pnf.PersonAID IS NULL
Спасибо за уточнение. В одной связи и впрямь ошибся (вечер, однака)
PersonAID — id персоны, исходной для отношения. (если я кого то лайкаю — то А — это мой id)
PersonBID — id второго человека, к которому применяется отношение (тот, кого я лайкнул)
Можно, конечно, обойтись без исходной таблицы Person, но так немного нагляднее получается.
ЗЫ: Таблица, соответственно, состоит из PersonAID, PersonBID, RelationShip. =)
Как бы нет (или вы боретесь просто за то что бы буковок было меньше?).
«логических» связок столько же сколько и в функциональном примере.
Каждый вызов функции — такой же запрос к «структуре» где хранятся взаимоотношения. (таблице)
Это, собственно, и есть задача с двумя звёздочками.
Если человек лайкает кого то, и если дружит с человеком, который дружит с тем кого лайкает — он его выберет.
ЗЫ: вам выше правильно заметили. Вы придумали синтаксис (ок), но смысла в этом нет, потому что он не добавляет ни прозрачности, ни простора для оптимизации ни каких то ещё полезностей. Та же логика — вид сбоку. =)
SELECT
pl.PersonAID
,pf.PersonAID
,pff.PersonAID
FROM Persons AS p
--Лайки
JOIN PersonRelationShip AS pl ON pl.PersonAID = p.PersonID
AND pl.Relation = 'Like'
--Друзья
JOIN PersonRelationShip AS pf ON pf.PersonAID = p.PersonID
AND pf.Relation = 'Friend'
--Друзья Друзей
JOIN PersonRelationShip AS pff ON pff.PersonAID = pf.PersonID
AND pff.PersonBID = pl.PersonID
AND pff.Relation = 'Friend'
--Ещё не дружат
LEFT JOIN PersonRelationShip AS pnf ON pnf.PersonAID = p.PersonID
AND pnf.PersonBID = pff.PersonBID
AND pnf.Relation = 'Friend'
WHERE pnf.PersonAID IS NULL
Это сложно?
Можно по аналогии с функционалом сделать через экзисты.
А можно ещё через рекурсию указывать количество «рук» друзей.
Итд итп.
ЗЫ: единственное, это MS SQL, но не думаю что он сильно отличается от постгре.
т.е. ты сравниваешь свой опыт с тем… чего не знаешь?
ЗЫ: и, да, я открою секрет — сколько занимает работа никак не зависит от того, фрилансишь ты или работаешь на корпорацию или ещё что то. Это просто вопрос организации своего труда.
Я спокойно, работая в офисе, работал те же 2-4 часа в день, а остальное проводил как хотел (с семьёй, к примеру).
При этом была возможность инвестировать и обеспечивать достойный доход. (хотя, конечно, зависит от того, сколько считать «достойным доходом»- если 30к рублей, то одно дело, если в десять раз больше — немного другое)
А так же была стабильность наличия работы, индексации зарплаты и развития профессиональных навыков на фоне резвития системы и интеграции её с другими.
Я же и говорю, на нас с Вами разные понятия о лидерстве свободе и развитии.
Э-э, а зачем свои то?
Свой бизнес, ну так, в среднем — это шарашкина контора разного уровня пошиба.
А вот кусок чего-нибудь серьёзного и крупного — это НАМНОГО интереснее. И меньше рисков, кстати.
Слово «автономный» означает, что человек может свой проект сам развивать. Или часть проекта. Или задачи. Без контроля и указки сверху. т.е. тот кому не нужен менеджер и ещё какие то административные костыли (аналитики? тестировщики? тех.писатели?).
ЗЫ: и, да — люди развиваются в крупных и сложных системах, которые дают людям «вызов» или тупо заставляют его работать и развиваться. Фриланс, обычно, как раз почти не развивается в силу специфики своих задач и отношений с заказчиками.
ЗЫЫ: немного оффтопа — а в насколько рупных корпоративных проектах ты работал, что бы сравнивать, если не секрет? )
Максимум — которые могут перебирать варианты быстрее людей… но это ж разве ум.
Но здоровый пофигизм — это черта очень здорового в моральном плане человека.
И, да — если никакого смысла в том, что бы доказывать другим что ты прав нет, то зачем это доказывать?
Какие пет проекты могут быть у SQLщика? )
О каких новых фреймворках идёт речь, когда найти работу в крупной компании на Delphi 5-7 и SQL 2008 совершенно непроблема? )
О каком количестве кода за час идёт речь, когда мне больше всего платят как раз когда я УМЕНЬШАЮ кодовую базу или переписываю существующую? Или просто ПЛАНИРУЮ как я буду это делать? )
Программисты формулируют задачи? Што? Может они их будут реализовывать, а формулировать и ставить специальные люди? (аналитики?) А то когда программист сам себе ставит задачи — это как то… опасненько.
Про английский язык — вообще жара. 15 лет программирую в разных проектах — ни разу не пригодился. Как в прочем и ни одному из коллег, кроме одного, который решил уехать за границу. Может я что то делаю не так? Или это речь о тех, кто работает фрилансом и по удалёнке? )
GitHub… да-да… опенсорс энтерпрайз решения… банки работающие на опенсорсных системах… государственные системы… ага-ага. И тем более делающие это через гитхаб. И, вдвойне, СОБИРАЮЩИЕ ФОЛОВЕРОВ. Боже.
А уж про то что нужно вокруг себя окружение собирать… зачем? Ну вот зачем?
Вопрос в том, что ты чувствуешь в себе такое право.
Сказать начальнику, что он не прав, когда он не прав. (многие не могут для себя даже рассмотреть такую возможность, даже при лояльном начальнике)
Не оправдываться, когда ты прав или допустил ошибку, а просто признать её или отстоять свою правоту.
Многие не чувствуют в себе этого права и, как следствие копят в себе негатив, понижают самооценку и совершенно теряют связь с реальностью, когда им предоставляется возможность стать самостоятельной личностью, а не ведомой любым из окружающих людей.
Смысл статьи не в том, что бы устраивать бунт, или плевать начальству в лицо, а в том, что бы трезво оценивать свою правоту, иметь свою волю и быть живым человеком, а не подстилкой. Это делает людей эффективнее, увереннее в себе, инициативней, снижает стресс и увеличивает жизненный тонус. И не желать такого коллегам или подчинённым могут только те, кто активно пользуется человеческой беспомощностью.
В плане производительности — это один констант скан, вместо двух или целых двух запросов к таблице, так что всяко лучше.
=)
select
t.first_person_id,
t.second_person_id,
c.dummy_first_person_id,
c.dummy_second_person_id
from friends as t
cross apply (values
(t.first_person_id, t.second_person_id),
(t.second_person_id, t.first_person_id)
) as c(dummy_first_person_id, dummy_second_person_id)
)
лучше Union, спасибо )
Если отношения
1 3 L
1 2 F
2 3 F
Какие данные вернёт этот скрипт?
*там в selec части немного не те данные и лишние запятые
1. В нём есть много опечаток )
2. В нём проверка только на одностороннее неналичие в друзьях (насколько я понял)
3. План, в принципе, строится такой же. =D
4. Сравнивал Ваш вариант и свой и нашёл ещё ошибку. Да что за жизнь то )
Скорее всего он будет практически идентичен плану вашего запроса:
6 индекс сиков (в случае поиска по одной персоне) и два скана.
Или все 8 сканов, если поиск производится «вообще».
Возможно, с изменением статистики по таблицы план изменится в ту или иную сторону.
В любом случае — а кто вам сказал, что гипотетический функциональный язык сможет сделать это оптимальнее? )
К примеру, несимметричные отношения, по моему пониманию, подразумевали что нужно брать только тех, кого Я лайкнул и кого выбрал другом человек, которого выбрал другом Я.
А те, кого я не лайкнул, а кто меня лайкал в таком случае не должны попасть в выборку.
Но если не важно направление связи — то я описал варианты чуть выше.
Спасибо за живое участие, посмотрите, вдруг я и там опечатался )
Руки никак не дойдут создать таки эти таблицы и сделать тесты. Работа-с.
К примеру
Связи хранятся в одностороннем виде.
т.е. если (условно) отношения представлены в виде двух строчек в таблице.
ID 12352 PersonAID 100 PersonBID 101 RelationShip 'Like'
ID 12353 PersonAID 101 PersonBID 100 RelationShip 'Like'
Если вы понимаете о чём я.
Тогда как то так:
Хотел описать второй вариант, с экономией строк (когда в каждой строке хранится PersonAID, PersonBID, Relation и RelationTypeID: 1 от А к Б, 2 от Б к А, 3 — взаимно), но такой вариант сводится к первому на самом деле. =)
Спасибо что указали )
К сожалению, вчерашний коментарий я не могу отредактировать =(
Спасибо за уточнение. В одной связи и впрямь ошибся (вечер, однака)
PersonBID — id второго человека, к которому применяется отношение (тот, кого я лайкнул)
Можно, конечно, обойтись без исходной таблицы Person, но так немного нагляднее получается.
ЗЫ: Таблица, соответственно, состоит из PersonAID, PersonBID, RelationShip. =)
«логических» связок столько же сколько и в функциональном примере.
Каждый вызов функции — такой же запрос к «структуре» где хранятся взаимоотношения. (таблице)
Это, собственно, и есть задача с двумя звёздочками.
Если человек лайкает кого то, и если дружит с человеком, который дружит с тем кого лайкает — он его выберет.
ЗЫ: вам выше правильно заметили. Вы придумали синтаксис (ок), но смысла в этом нет, потому что он не добавляет ни прозрачности, ни простора для оптимизации ни каких то ещё полезностей. Та же логика — вид сбоку. =)
Это сложно?
Можно по аналогии с функционалом сделать через экзисты.
А можно ещё через рекурсию указывать количество «рук» друзей.
Итд итп.
ЗЫ: единственное, это MS SQL, но не думаю что он сильно отличается от постгре.
А как лидерство связано с тем на кого ты работаешь?
И понять, что ты сравниваешь свой опыт с опытом, которого не имеешь.
ЗЫ: и, да, я открою секрет — сколько занимает работа никак не зависит от того, фрилансишь ты или работаешь на корпорацию или ещё что то. Это просто вопрос организации своего труда.
Я спокойно, работая в офисе, работал те же 2-4 часа в день, а остальное проводил как хотел (с семьёй, к примеру).
При этом была возможность инвестировать и обеспечивать достойный доход. (хотя, конечно, зависит от того, сколько считать «достойным доходом»- если 30к рублей, то одно дело, если в десять раз больше — немного другое)
А так же была стабильность наличия работы, индексации зарплаты и развития профессиональных навыков на фоне резвития системы и интеграции её с другими.
и в чём же?
Свой бизнес, ну так, в среднем — это шарашкина контора разного уровня пошиба.
А вот кусок чего-нибудь серьёзного и крупного — это НАМНОГО интереснее. И меньше рисков, кстати.
Слово «автономный» означает, что человек может свой проект сам развивать. Или часть проекта. Или задачи. Без контроля и указки сверху. т.е. тот кому не нужен менеджер и ещё какие то административные костыли (аналитики? тестировщики? тех.писатели?).
ЗЫ: и, да — люди развиваются в крупных и сложных системах, которые дают людям «вызов» или тупо заставляют его работать и развиваться. Фриланс, обычно, как раз почти не развивается в силу специфики своих задач и отношений с заказчиками.
ЗЫЫ: немного оффтопа — а в насколько рупных корпоративных проектах ты работал, что бы сравнивать, если не секрет? )